nex-framework-cli 1.0.18 → 1.0.20

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/cli/nex-cli.js CHANGED
@@ -28,7 +28,7 @@ program.configureHelp({
28
28
  program
29
29
  .name('nex')
30
30
  .description('NEX Framework - Framework completo de agentes AI')
31
- .version('1.0.18', '-v, --version', 'Mostra a versão')
31
+ .version('1.0.19', '-v, --version', 'Mostra a versão')
32
32
  .addHelpText('before', chalk.bold.cyan(`
33
33
  ╔════════════════════════════════════════════════════════════════╗
34
34
  ║ NEX Framework - CLI v1.0.9 ║
@@ -64,12 +64,26 @@ Exemplos:
64
64
  console.log(chalk.blue('🚀 Inicializando projeto NEX...'))
65
65
  console.log()
66
66
 
67
+ // Detectar nome do projeto atual (da pasta ou package.json)
68
+ let currentProjectName = path.basename(process.cwd())
69
+ try {
70
+ const packageJsonPath = path.join(process.cwd(), 'package.json')
71
+ if (await fs.pathExists(packageJsonPath)) {
72
+ const packageJson = await fs.readJSON(packageJsonPath)
73
+ if (packageJson.name) {
74
+ currentProjectName = packageJson.name
75
+ }
76
+ }
77
+ } catch (error) {
78
+ // Ignore errors
79
+ }
80
+
67
81
  const answers = await inquirer.prompt([
68
82
  {
69
83
  type: 'input',
70
84
  name: 'projectName',
71
85
  message: 'Nome do projeto:',
72
- default: options.name || 'nex-project',
86
+ default: options.name || currentProjectName,
73
87
  when: !options.name
74
88
  },
75
89
  {
@@ -85,10 +99,10 @@ Exemplos:
85
99
  const projectName = options.name || answers.projectName
86
100
  const template = options.template || answers.template
87
101
 
88
- // Criar estrutura do projeto (sem config, usa global)
89
- await createProjectStructure(projectName, template)
102
+ // Criar estrutura do projeto no diretório atual (não criar nova pasta)
103
+ await createProjectStructure(projectName, template, true)
90
104
 
91
- console.log(chalk.green(`\n✅ Projeto ${projectName} criado com sucesso!`))
105
+ console.log(chalk.green(`\n✅ Projeto ${projectName} inicializado com sucesso!`))
92
106
  console.log()
93
107
  })
94
108
 
@@ -342,25 +356,42 @@ program
342
356
  })
343
357
 
344
358
  // Comando: config
345
- program
359
+ const configCmd = program
346
360
  .command('config')
347
- .description('Gerencia configurações')
348
- .option('get <key>', 'Obtém valor de configuração')
349
- .option('set <key> <value>', 'Define valor de configuração')
350
- .option('list', 'Lista todas as configurações')
351
- .action(async (options) => {
352
- if (options.get) {
353
- // Obter configuração
354
- } else if (options.set) {
355
- // Definir configuração
356
- } else if (options.list) {
357
- // Listar configurações
358
- }
361
+ .description('Gerencia configurações do NEX CLI')
362
+
363
+ configCmd
364
+ .command('reset')
365
+ .description('Reconfigura o NEX CLI (nome, idiomas, integração Cursor)')
366
+ .action(async () => {
367
+ const { runSetup } = await import('../scripts/postinstall.js')
368
+ await runSetup(true) // Force reconfiguration
369
+ })
370
+
371
+ configCmd
372
+ .command('show')
373
+ .alias('list')
374
+ .description('Mostra a configuração atual')
375
+ .action(async () => {
376
+ const { default: NEXMarketplace } = await import('../src/services/nex-marketplace/NEXMarketplace.js')
377
+ const marketplace = new NEXMarketplace()
378
+ const config = marketplace.getGlobalConfig()
379
+
380
+ console.log(chalk.blue('\n⚙️ Configuração do NEX CLI\n'))
381
+ console.log(chalk.gray('Usuário:'))
382
+ console.log(chalk.white(` Nome: ${config.user.name}`))
383
+ console.log(chalk.white(` Idioma de conversação: ${config.user.conversationLanguage}`))
384
+ console.log(chalk.white(` Idioma de documentos: ${config.user.documentLanguage}`))
385
+ console.log(chalk.gray('\nCursor:'))
386
+ console.log(chalk.white(` Integração: ${config.cursor.enabled ? chalk.green('Habilitada') : chalk.red('Desabilitada')}`))
387
+
388
+ const configPath = marketplace.getGlobalConfigPath()
389
+ console.log(chalk.gray(`\nArquivo: ${configPath}\n`))
359
390
  })
360
391
 
361
392
  // Funções auxiliares
362
- async function createProjectStructure(projectName, template) {
363
- const projectDir = path.join(process.cwd(), projectName)
393
+ async function createProjectStructure(projectName, template, useCurrentDir = false) {
394
+ const projectDir = useCurrentDir ? process.cwd() : path.join(process.cwd(), projectName)
364
395
  await fs.ensureDir(projectDir)
365
396
 
366
397
  // Criar estrutura básica
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nex-framework-cli",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "NEX CLI - Command-line interface for NEX Framework and Agent Marketplace",
5
5
  "type": "module",
6
6
  "main": "cli/nex-cli.js",
@@ -15,7 +15,7 @@ const __filename = fileURLToPath(import.meta.url)
15
15
  const __dirname = path.dirname(__filename)
16
16
 
17
17
  // Get global config path
18
- function getGlobalConfigPath() {
18
+ export function getGlobalConfigPath() {
19
19
  const homeDir = os.homedir()
20
20
 
21
21
  if (process.platform === 'win32') {
@@ -27,20 +27,30 @@ function getGlobalConfigPath() {
27
27
  }
28
28
  }
29
29
 
30
- async function runSetup() {
30
+ export async function runSetup(force = false) {
31
31
  // Check if config already exists
32
32
  const configPath = getGlobalConfigPath()
33
33
  const configDir = path.dirname(configPath)
34
34
 
35
- if (await fs.pathExists(configPath)) {
35
+ if (!force && await fs.pathExists(configPath)) {
36
36
  try {
37
37
  const existingConfig = await fs.readJSON(configPath)
38
- // If config exists and is valid, skip setup
38
+ // If config exists and is valid, ask if user wants to reconfigure
39
39
  if (existingConfig.user && existingConfig.user.name) {
40
- console.log(chalk.green('\n✅ NEX CLI está configurado!'))
41
- console.log(chalk.gray(` Config: ${configPath}`))
42
- console.log(chalk.gray(` Para reconfigurar, delete o arquivo ou execute: nex config reset\n`))
43
- return
40
+ const { overwrite } = await inquirer.prompt([
41
+ {
42
+ type: 'confirm',
43
+ name: 'overwrite',
44
+ message: 'NEX CLI já está configurado. Deseja reconfigurar?',
45
+ default: false
46
+ }
47
+ ])
48
+
49
+ if (!overwrite) {
50
+ console.log(chalk.green('\n✅ Configuração mantida.'))
51
+ console.log(chalk.gray(` Config: ${configPath}\n`))
52
+ return
53
+ }
44
54
  }
45
55
  } catch (error) {
46
56
  // Config file exists but is invalid, continue with setup
@@ -106,7 +116,7 @@ async function runSetup() {
106
116
  enabled: answers.cursorIntegration
107
117
  },
108
118
  installedAt: new Date().toISOString(),
109
- version: '1.0.18'
119
+ version: '1.0.19'
110
120
  }
111
121
 
112
122
  // Save config
@@ -122,8 +132,16 @@ async function runSetup() {
122
132
  console.log(chalk.cyan('\n💡 Dica: Para reconfigurar, execute: nex config reset\n'))
123
133
  }
124
134
 
125
- // Only run if not in CI/CD or if explicitly requested
126
- if (process.env.CI !== 'true' && process.env.NEX_SKIP_SETUP !== 'true') {
135
+ // Check if running in interactive mode (TTY available)
136
+ const isInteractive = process.stdin.isTTY && process.stdout.isTTY && process.stderr.isTTY
137
+ const isCI = process.env.CI === 'true'
138
+ const skipSetup = process.env.NEX_SKIP_SETUP === 'true'
139
+
140
+ // Only run interactive setup if:
141
+ // 1. Not in CI
142
+ // 2. Not explicitly skipped
143
+ // 3. Running in interactive mode (TTY)
144
+ if (!isCI && !skipSetup && isInteractive) {
127
145
  runSetup().catch((error) => {
128
146
  console.error(chalk.red('\n❌ Erro ao configurar NEX CLI:'))
129
147
  console.error(chalk.red(error.message))
@@ -131,12 +149,12 @@ if (process.env.CI !== 'true' && process.env.NEX_SKIP_SETUP !== 'true') {
131
149
  process.exit(0) // Don't fail the install
132
150
  })
133
151
  } else {
134
- // In CI/CD, create default config silently
152
+ // Non-interactive mode: create default config silently
135
153
  const configPath = getGlobalConfigPath()
136
154
  const configDir = path.dirname(configPath)
137
155
  const defaultConfig = {
138
156
  user: {
139
- name: 'Developer',
157
+ name: process.env.USER || process.env.USERNAME || 'Developer',
140
158
  conversationLanguage: 'pt-BR',
141
159
  documentLanguage: 'pt-BR'
142
160
  },
@@ -144,12 +162,18 @@ if (process.env.CI !== 'true' && process.env.NEX_SKIP_SETUP !== 'true') {
144
162
  enabled: false
145
163
  },
146
164
  installedAt: new Date().toISOString(),
147
- version: '1.0.18'
165
+ version: '1.0.19'
148
166
  }
149
167
 
150
168
  fs.ensureDir(configDir)
151
169
  .then(() => fs.writeJSON(configPath, defaultConfig, { spaces: 2 }))
170
+ .then(() => {
171
+ if (!isCI && isInteractive) {
172
+ console.log(chalk.green('\n✅ NEX CLI instalado com configuração padrão'))
173
+ console.log(chalk.gray(' Para configurar: nex config reset\n'))
174
+ }
175
+ })
152
176
  .catch(() => {
153
- // Silently fail in CI
177
+ // Silently fail in non-interactive mode
154
178
  })
155
179
  }
@@ -1087,8 +1087,8 @@ export default class NEXMarketplace {
1087
1087
  const mainCursorRulesPath = path.join(this.projectRoot, '.cursorrules')
1088
1088
  const importLine = `import .cursorrules/${rulesFile}`
1089
1089
  const commentLine = `# ${manifest.name} - ${manifest.tagline || manifest.description?.substring(0, 50)}`
1090
- const trigger = manifest.bmad?.activation_trigger || `@${agentId}`
1091
- const agentComment = `# Use: ${trigger} <command>`
1090
+ const agentTrigger = manifest.bmad?.activation_trigger || `@${agentId}`
1091
+ const agentComment = `# Use: ${agentTrigger} <command>`
1092
1092
 
1093
1093
  let cursorRulesContent = ''
1094
1094
  if (await fs.pathExists(mainCursorRulesPath)) {
@@ -1112,8 +1112,7 @@ export default class NEXMarketplace {
1112
1112
 
1113
1113
  console.log(chalk.green(`\n✅ Cursor integration complete!`))
1114
1114
  console.log(chalk.gray(` Added ${rulesFile} to .cursorrules`))
1115
- const trigger = manifest.bmad?.activation_trigger || `@${agentId}`
1116
- console.log(chalk.gray(` Use: ${trigger} <command> in Cursor\n`))
1115
+ console.log(chalk.gray(` Use: ${agentTrigger} <command> in Cursor\n`))
1117
1116
 
1118
1117
  } catch (error) {
1119
1118
  console.log(chalk.yellow(`\n⚠️ Cursor integration failed: ${error.message}`))