nex-app 2.0.0 → 2.0.2
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 +39 -9
- package/nex/vex.md +23 -0
- package/package.json +4 -3
- package/scripts/install-cursor-rules.js +54 -22
package/cli/nex-cli.js
CHANGED
|
@@ -22,7 +22,15 @@ const program = new Command()
|
|
|
22
22
|
program
|
|
23
23
|
.name('nex')
|
|
24
24
|
.description('NEX Framework - Framework completo de agentes AI')
|
|
25
|
-
.version('2.0.
|
|
25
|
+
.version('2.0.2')
|
|
26
|
+
|
|
27
|
+
function getInstallerCommand() {
|
|
28
|
+
const node = process.execPath
|
|
29
|
+
const installerScript = path.join(__dirname, '..', 'scripts', 'install-cursor-rules.js')
|
|
30
|
+
const target = process.cwd()
|
|
31
|
+
// Importante: aspas para caminhos com espaços (Windows)
|
|
32
|
+
return `"${node}" "${installerScript}" --target "${target}"`
|
|
33
|
+
}
|
|
26
34
|
|
|
27
35
|
// Setup Wizard (executa quando sem comandos)
|
|
28
36
|
async function runSetupWizard() {
|
|
@@ -49,20 +57,19 @@ async function runSetupWizard() {
|
|
|
49
57
|
console.log(chalk.yellow('\n📦 Installing NEX Cursor Rules...\n'))
|
|
50
58
|
|
|
51
59
|
try {
|
|
52
|
-
// Executar
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
shell: true
|
|
56
|
-
})
|
|
60
|
+
// Executar instalador do PRÓPRIO pacote (não depende do package.json do projeto)
|
|
61
|
+
const cmd = getInstallerCommand()
|
|
62
|
+
const { stdout } = await execAsync(cmd, { cwd: process.cwd(), shell: true })
|
|
57
63
|
console.log(stdout)
|
|
58
64
|
|
|
59
65
|
console.log(chalk.green('\n✅ NEX Cursor Rules installed successfully!\n'))
|
|
60
66
|
console.log(chalk.cyan('Usage:'))
|
|
67
|
+
console.log(chalk.white(' • Validation agent: @vex'))
|
|
61
68
|
console.log(chalk.white(' • In Cursor: @nex/core/agents/nex-master'))
|
|
62
69
|
console.log(chalk.white(' • List all: @nex/index\n'))
|
|
63
70
|
} catch (error) {
|
|
64
71
|
console.log(chalk.yellow('⚠️ Could not auto-install. Run manually:'))
|
|
65
|
-
console.log(chalk.white('
|
|
72
|
+
console.log(chalk.white(' npx nex-app@latest install\n'))
|
|
66
73
|
}
|
|
67
74
|
}
|
|
68
75
|
|
|
@@ -72,7 +79,7 @@ async function runSetupWizard() {
|
|
|
72
79
|
|
|
73
80
|
try {
|
|
74
81
|
// Tentar abrir o browser
|
|
75
|
-
const url = 'https://nex.inosx.com/hub'
|
|
82
|
+
const url = 'https://nex-store.inosx.com/hub'
|
|
76
83
|
const command = process.platform === 'win32' ? 'start' :
|
|
77
84
|
process.platform === 'darwin' ? 'open' : 'xdg-open'
|
|
78
85
|
|
|
@@ -80,7 +87,7 @@ async function runSetupWizard() {
|
|
|
80
87
|
console.log(chalk.green(`✅ NEX Hub opened at ${url}\n`))
|
|
81
88
|
} catch (error) {
|
|
82
89
|
console.log(chalk.yellow(`⚠️ Could not auto-open browser. Visit manually:`))
|
|
83
|
-
console.log(chalk.white(` https://nex.inosx.com/hub\n`))
|
|
90
|
+
console.log(chalk.white(` https://nex-store.inosx.com/hub\n`))
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
|
|
@@ -100,6 +107,29 @@ program
|
|
|
100
107
|
await runSetupWizard()
|
|
101
108
|
})
|
|
102
109
|
|
|
110
|
+
// Instala as regras do Cursor no projeto atual (útil fora do wizard)
|
|
111
|
+
program
|
|
112
|
+
.command('install')
|
|
113
|
+
.description('Instala regras do NEX no Cursor (.cursor/rules/nex/) no projeto atual')
|
|
114
|
+
.action(async () => {
|
|
115
|
+
const cmd = getInstallerCommand()
|
|
116
|
+
const { stdout } = await execAsync(cmd, { cwd: process.cwd(), shell: true })
|
|
117
|
+
console.log(stdout)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
// Valida as regras do Cursor no projeto atual
|
|
121
|
+
program
|
|
122
|
+
.command('validate')
|
|
123
|
+
.description('Valida se as regras do NEX estão instaladas no projeto atual')
|
|
124
|
+
.action(async () => {
|
|
125
|
+
const node = process.execPath
|
|
126
|
+
const installerScript = path.join(__dirname, '..', 'scripts', 'install-cursor-rules.js')
|
|
127
|
+
const target = process.cwd()
|
|
128
|
+
const cmd = `"${node}" "${installerScript}" --validate --target "${target}"`
|
|
129
|
+
const { stdout } = await execAsync(cmd, { cwd: process.cwd(), shell: true })
|
|
130
|
+
console.log(stdout)
|
|
131
|
+
})
|
|
132
|
+
|
|
103
133
|
// Comando: init
|
|
104
134
|
program
|
|
105
135
|
.command('init')
|
package/nex/vex.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Vex - NEX Agent
|
|
2
|
+
|
|
3
|
+
O **Vex** é um agente do NEX focado em **validação, consistência e rigor**.
|
|
4
|
+
|
|
5
|
+
## Quando usar o Vex
|
|
6
|
+
|
|
7
|
+
- **Antes de publicar** (npm / releases): checklist, riscos, “o que pode dar errado”
|
|
8
|
+
- **Depois de mudar regras/agents**: valida se a estrutura e os handles do Cursor estão coerentes
|
|
9
|
+
- **Quando algo “não ativa” no Cursor**: diagnóstico rápido e passos objetivos
|
|
10
|
+
|
|
11
|
+
## Como falar comigo
|
|
12
|
+
|
|
13
|
+
Diga em 1 frase:
|
|
14
|
+
|
|
15
|
+
- **Objetivo** (o que você quer validar/garantir)
|
|
16
|
+
- **Contexto** (onde está rodando, qual comando, qual erro)
|
|
17
|
+
- **Resultado esperado** (o que deve acontecer)
|
|
18
|
+
|
|
19
|
+
Exemplos:
|
|
20
|
+
|
|
21
|
+
- “Valide se `npx nex-app@latest` instala corretamente no meu projeto e se o Cursor reconhece `@nex/index`.”
|
|
22
|
+
- “Meu `@nex/core/agents/nex-master` não aparece no Cursor; me diga o checklist mínimo para corrigir.”
|
|
23
|
+
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nex-app",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "NEX 2.0 - Multi-LLM AI Framework with Cursor Rules Integration | The easiest way to use AI agents in your development workflow",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "cli/nex-cli.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"nex": "
|
|
8
|
+
"nex-app": "cli/nex-cli.js",
|
|
9
|
+
"nex": "cli/nex-cli.js"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"cli/",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"license": "PROPRIETARY",
|
|
57
58
|
"repository": {
|
|
58
59
|
"type": "git",
|
|
59
|
-
"url": "https://github.com/INOSX/nex-store.git"
|
|
60
|
+
"url": "git+https://github.com/INOSX/nex-store.git"
|
|
60
61
|
},
|
|
61
62
|
"bugs": {
|
|
62
63
|
"url": "https://github.com/INOSX/nex-store/issues"
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Instala apenas o essencial:
|
|
7
7
|
* - nex-master (agente principal)
|
|
8
|
+
* - vex (agente de validação)
|
|
8
9
|
* - workflows básicos do core
|
|
9
10
|
*
|
|
10
11
|
* Uso:
|
|
11
12
|
* node scripts/install-cursor-rules.js
|
|
12
13
|
* node scripts/install-cursor-rules.js --validate
|
|
14
|
+
* node scripts/install-cursor-rules.js --target <caminho-do-projeto>
|
|
13
15
|
*/
|
|
14
16
|
|
|
15
17
|
import fs from 'fs-extra'
|
|
@@ -20,12 +22,13 @@ import chalk from 'chalk'
|
|
|
20
22
|
const __filename = fileURLToPath(import.meta.url)
|
|
21
23
|
const __dirname = path.dirname(__filename)
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
const
|
|
25
|
+
// O pacote (fonte) fica relativo a este arquivo.
|
|
26
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..')
|
|
27
|
+
const NEX_SOURCE = path.join(PACKAGE_ROOT, 'nex')
|
|
26
28
|
|
|
27
29
|
// Arquivos essenciais para instalar
|
|
28
30
|
const ESSENTIAL_FILES = [
|
|
31
|
+
'nex/vex.md',
|
|
29
32
|
'nex/core/agents/nex-master.md',
|
|
30
33
|
'nex/core/workflows/brainstorming/instructions.md',
|
|
31
34
|
'nex/core/workflows/party-mode/instructions.md'
|
|
@@ -37,6 +40,26 @@ const CONFIG = {
|
|
|
37
40
|
verbose: true
|
|
38
41
|
}
|
|
39
42
|
|
|
43
|
+
function parseArgs(argv) {
|
|
44
|
+
const args = argv.slice(2)
|
|
45
|
+
const result = {
|
|
46
|
+
validate: args.includes('--validate'),
|
|
47
|
+
target: undefined
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const targetIdx = args.findIndex(a => a === '--target')
|
|
51
|
+
if (targetIdx !== -1 && args[targetIdx + 1]) {
|
|
52
|
+
result.target = args[targetIdx + 1]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return result
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function resolveTargetRoot(targetArg) {
|
|
59
|
+
// Por padrão: instala no projeto atual (onde o usuário rodou o comando)
|
|
60
|
+
return path.resolve(targetArg || process.cwd())
|
|
61
|
+
}
|
|
62
|
+
|
|
40
63
|
// ============================================================================
|
|
41
64
|
// Log Functions
|
|
42
65
|
// ============================================================================
|
|
@@ -117,7 +140,7 @@ function convertToMDC(sourceFile, targetFile) {
|
|
|
117
140
|
// Escrever arquivo .mdc
|
|
118
141
|
fs.writeFileSync(targetFile, mdcContent, 'utf-8')
|
|
119
142
|
|
|
120
|
-
log(`Created: ${
|
|
143
|
+
log(`Created: ${targetFile}`, 'success')
|
|
121
144
|
return true
|
|
122
145
|
} catch (error) {
|
|
123
146
|
log(`Error converting ${sourceFile}: ${error.message}`, 'error')
|
|
@@ -129,8 +152,8 @@ function convertToMDC(sourceFile, targetFile) {
|
|
|
129
152
|
// Create Index
|
|
130
153
|
// ============================================================================
|
|
131
154
|
|
|
132
|
-
function createIndex() {
|
|
133
|
-
const indexPath = path.join(
|
|
155
|
+
function createIndex(cursorRulesDir) {
|
|
156
|
+
const indexPath = path.join(cursorRulesDir, 'index.mdc')
|
|
134
157
|
|
|
135
158
|
const indexContent = `---
|
|
136
159
|
description: NEX Framework - Cursor Rules Index
|
|
@@ -150,12 +173,16 @@ NEX rules have been installed to: \`.cursor/rules/nex/\`
|
|
|
150
173
|
|
|
151
174
|
## How to Use
|
|
152
175
|
|
|
176
|
+
- Reference Vex (validation agent): **@vex** (or **@nex/vex**)
|
|
153
177
|
- Reference the master agent: **@nex/core/agents/nex-master**
|
|
154
178
|
- Reference workflows: **@nex/core/workflows/brainstorming** or **@nex/core/workflows/party-mode**
|
|
155
179
|
- Reference this index: **@nex/index**
|
|
156
180
|
|
|
157
181
|
## Installed Components
|
|
158
182
|
|
|
183
|
+
### Core Agent (Validation)
|
|
184
|
+
- @vex - Vex (validation, consistency, troubleshooting)
|
|
185
|
+
|
|
159
186
|
### Core Agent
|
|
160
187
|
- @nex/core/agents/nex-master - NEX Master Agent (your main AI assistant)
|
|
161
188
|
|
|
@@ -176,8 +203,7 @@ Reference them explicitly when you need specific functionality.
|
|
|
176
203
|
|
|
177
204
|
---
|
|
178
205
|
|
|
179
|
-
**Project:** nex-
|
|
180
|
-
**Version:** 2.0.0
|
|
206
|
+
**Project:** NEX (installed via nex-app)
|
|
181
207
|
**Created:** ${new Date().toISOString()}
|
|
182
208
|
`
|
|
183
209
|
|
|
@@ -195,7 +221,7 @@ Reference them explicitly when you need specific functionality.
|
|
|
195
221
|
// Main Install Function
|
|
196
222
|
// ============================================================================
|
|
197
223
|
|
|
198
|
-
async function install() {
|
|
224
|
+
async function install(targetRoot) {
|
|
199
225
|
console.log(chalk.bold.blue('\n🚀 NEX Cursor Rules Installer (Simplified)\n'))
|
|
200
226
|
|
|
201
227
|
let successCount = 0
|
|
@@ -203,13 +229,14 @@ async function install() {
|
|
|
203
229
|
|
|
204
230
|
// Criar diretório .cursor/rules/nex
|
|
205
231
|
log('Creating directory structure...', 'info')
|
|
206
|
-
|
|
232
|
+
const cursorRulesDir = path.join(targetRoot, '.cursor', 'rules', 'nex')
|
|
233
|
+
fs.ensureDirSync(cursorRulesDir)
|
|
207
234
|
|
|
208
235
|
// Processar arquivos essenciais
|
|
209
236
|
log('\nInstalling essential NEX components...', 'info')
|
|
210
237
|
|
|
211
238
|
for (const relativePath of ESSENTIAL_FILES) {
|
|
212
|
-
const sourceFile = path.join(
|
|
239
|
+
const sourceFile = path.join(PACKAGE_ROOT, relativePath)
|
|
213
240
|
|
|
214
241
|
if (!fs.existsSync(sourceFile)) {
|
|
215
242
|
log(`File not found: ${relativePath}`, 'warning')
|
|
@@ -218,7 +245,7 @@ async function install() {
|
|
|
218
245
|
|
|
219
246
|
// Determinar caminho de destino
|
|
220
247
|
const relativeToNex = path.relative(NEX_SOURCE, sourceFile)
|
|
221
|
-
const targetFile = path.join(
|
|
248
|
+
const targetFile = path.join(cursorRulesDir, relativeToNex.replace('.md', '.mdc'))
|
|
222
249
|
|
|
223
250
|
// Converter
|
|
224
251
|
if (convertToMDC(sourceFile, targetFile)) {
|
|
@@ -230,7 +257,7 @@ async function install() {
|
|
|
230
257
|
|
|
231
258
|
// Criar index.mdc
|
|
232
259
|
log('\nCreating index file...', 'info')
|
|
233
|
-
if (createIndex()) {
|
|
260
|
+
if (createIndex(cursorRulesDir)) {
|
|
234
261
|
successCount++
|
|
235
262
|
} else {
|
|
236
263
|
errorCount++
|
|
@@ -244,10 +271,11 @@ async function install() {
|
|
|
244
271
|
}
|
|
245
272
|
|
|
246
273
|
console.log(chalk.cyan('\n📖 Usage:'))
|
|
274
|
+
console.log(chalk.white(' Validation agent: @vex'))
|
|
247
275
|
console.log(chalk.white(' In Cursor, type: @nex/core/agents/nex-master'))
|
|
248
276
|
console.log(chalk.white(' Or reference: @nex/index\n'))
|
|
249
277
|
|
|
250
|
-
console.log(chalk.gray(
|
|
278
|
+
console.log(chalk.gray(` Files installed in: ${cursorRulesDir}\n`))
|
|
251
279
|
|
|
252
280
|
return errorCount === 0
|
|
253
281
|
}
|
|
@@ -256,14 +284,16 @@ async function install() {
|
|
|
256
284
|
// Validate Function
|
|
257
285
|
// ============================================================================
|
|
258
286
|
|
|
259
|
-
async function validate() {
|
|
287
|
+
async function validate(targetRoot) {
|
|
260
288
|
console.log(chalk.bold.blue('\n🔍 NEX Installation Validator\n'))
|
|
261
289
|
|
|
262
290
|
let validCount = 0
|
|
263
291
|
let invalidCount = 0
|
|
264
292
|
|
|
293
|
+
const cursorRulesDir = path.join(targetRoot, '.cursor', 'rules', 'nex')
|
|
294
|
+
|
|
265
295
|
// Verificar diretório
|
|
266
|
-
if (!fs.existsSync(
|
|
296
|
+
if (!fs.existsSync(cursorRulesDir)) {
|
|
267
297
|
log('NEX not installed (.cursor/rules/nex/ not found)', 'error')
|
|
268
298
|
return false
|
|
269
299
|
}
|
|
@@ -272,6 +302,7 @@ async function validate() {
|
|
|
272
302
|
|
|
273
303
|
// Verificar arquivos essenciais
|
|
274
304
|
const expectedFiles = [
|
|
305
|
+
'vex.mdc',
|
|
275
306
|
'core/agents/nex-master.mdc',
|
|
276
307
|
'core/workflows/brainstorming/instructions.mdc',
|
|
277
308
|
'core/workflows/party-mode/instructions.mdc',
|
|
@@ -279,7 +310,7 @@ async function validate() {
|
|
|
279
310
|
]
|
|
280
311
|
|
|
281
312
|
for (const file of expectedFiles) {
|
|
282
|
-
const filePath = path.join(
|
|
313
|
+
const filePath = path.join(cursorRulesDir, file)
|
|
283
314
|
if (fs.existsSync(filePath)) {
|
|
284
315
|
log(`✓ ${file}`, 'success')
|
|
285
316
|
validCount++
|
|
@@ -293,7 +324,7 @@ async function validate() {
|
|
|
293
324
|
console.log(chalk.white(`Valid: ${validCount}`))
|
|
294
325
|
if (invalidCount > 0) {
|
|
295
326
|
console.log(chalk.yellow(`Invalid: ${invalidCount}`))
|
|
296
|
-
console.log(chalk.cyan('\nRun:
|
|
327
|
+
console.log(chalk.cyan('\nRun: npx nex-app@latest install\n'))
|
|
297
328
|
}
|
|
298
329
|
|
|
299
330
|
return invalidCount === 0
|
|
@@ -303,17 +334,18 @@ async function validate() {
|
|
|
303
334
|
// Main
|
|
304
335
|
// ============================================================================
|
|
305
336
|
|
|
306
|
-
const
|
|
337
|
+
const parsed = parseArgs(process.argv)
|
|
338
|
+
const targetRoot = resolveTargetRoot(parsed.target)
|
|
307
339
|
|
|
308
|
-
if (
|
|
309
|
-
validate()
|
|
340
|
+
if (parsed.validate) {
|
|
341
|
+
validate(targetRoot)
|
|
310
342
|
.then(success => process.exit(success ? 0 : 1))
|
|
311
343
|
.catch(error => {
|
|
312
344
|
console.error(chalk.red(`\n✗ Validation failed: ${error.message}\n`))
|
|
313
345
|
process.exit(1)
|
|
314
346
|
})
|
|
315
347
|
} else {
|
|
316
|
-
install()
|
|
348
|
+
install(targetRoot)
|
|
317
349
|
.then(success => process.exit(success ? 0 : 1))
|
|
318
350
|
.catch(error => {
|
|
319
351
|
console.error(chalk.red(`\n✗ Installation failed: ${error.message}\n`))
|