nex-framework-cli 1.0.20 → 1.0.21
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.
|
|
31
|
+
.version('1.0.20', '-v, --version', 'Mostra a versão')
|
|
32
32
|
.addHelpText('before', chalk.bold.cyan(`
|
|
33
33
|
╔════════════════════════════════════════════════════════════════╗
|
|
34
34
|
║ NEX Framework - CLI v1.0.9 ║
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -116,7 +116,7 @@ export async function runSetup(force = false) {
|
|
|
116
116
|
enabled: answers.cursorIntegration
|
|
117
117
|
},
|
|
118
118
|
installedAt: new Date().toISOString(),
|
|
119
|
-
version: '1.0.
|
|
119
|
+
version: '1.0.20'
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// Save config
|
|
@@ -162,7 +162,7 @@ if (!isCI && !skipSetup && isInteractive) {
|
|
|
162
162
|
enabled: false
|
|
163
163
|
},
|
|
164
164
|
installedAt: new Date().toISOString(),
|
|
165
|
-
version: '1.0.
|
|
165
|
+
version: '1.0.20'
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
fs.ensureDir(configDir)
|
|
@@ -1021,98 +1021,103 @@ export default class NEXMarketplace {
|
|
|
1021
1021
|
}
|
|
1022
1022
|
|
|
1023
1023
|
/**
|
|
1024
|
-
* Integrate BMAD agent with Cursor
|
|
1024
|
+
* Integrate BMAD agent with Cursor (following BMAD pattern)
|
|
1025
|
+
* Creates .mdc files in .cursor/rules/nex/ similar to BMAD
|
|
1025
1026
|
*/
|
|
1026
1027
|
async integrateWithCursor(agentId, manifest, sourcePath) {
|
|
1027
1028
|
try {
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1029
|
+
// Get global config for user info
|
|
1030
|
+
const globalConfig = this.getGlobalConfig()
|
|
1031
|
+
const userConfig = globalConfig.user || {}
|
|
1032
|
+
|
|
1033
|
+
// Create NEX core config directory (similar to BMAD)
|
|
1034
|
+
const nexCoreDir = path.join(this.projectRoot, 'nex', 'core')
|
|
1035
|
+
await fs.ensureDir(nexCoreDir)
|
|
1036
|
+
|
|
1037
|
+
// Create config.yaml (similar to BMAD)
|
|
1038
|
+
const configYaml = {
|
|
1039
|
+
user_name: userConfig.name || 'Developer',
|
|
1040
|
+
communication_language: userConfig.conversationLanguage || 'pt-br',
|
|
1041
|
+
document_output_language: userConfig.documentLanguage || 'pt-br',
|
|
1042
|
+
output_folder: '{project-root}/docs'
|
|
1031
1043
|
}
|
|
1032
1044
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1045
|
+
const configPath = path.join(nexCoreDir, 'config.yaml')
|
|
1046
|
+
if (!await fs.pathExists(configPath)) {
|
|
1047
|
+
const configYamlContent = yaml.stringify(configYaml)
|
|
1048
|
+
await fs.writeFile(configPath, configYamlContent, 'utf8')
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// Create .cursor/rules/nex directory structure (following BMAD pattern)
|
|
1052
|
+
const cursorRulesDir = path.join(this.projectRoot, '.cursor', 'rules', 'nex')
|
|
1053
|
+
const agentCategory = manifest.category || 'bmad'
|
|
1054
|
+
const agentRulesDir = path.join(cursorRulesDir, agentCategory, 'agents')
|
|
1055
|
+
await fs.ensureDir(agentRulesDir)
|
|
1056
|
+
|
|
1057
|
+
// Check if agent has a README.md or similar file to convert to .mdc
|
|
1058
|
+
let agentContent = ''
|
|
1059
|
+
const possibleAgentFiles = [
|
|
1060
|
+
path.join(sourcePath, 'README.md'),
|
|
1061
|
+
path.join(sourcePath, `${agentId}.md`),
|
|
1062
|
+
path.join(sourcePath, 'agent.md')
|
|
1063
|
+
]
|
|
1064
|
+
|
|
1065
|
+
let agentFile = null
|
|
1066
|
+
for (const filePath of possibleAgentFiles) {
|
|
1067
|
+
if (await fs.pathExists(filePath)) {
|
|
1068
|
+
agentFile = filePath
|
|
1069
|
+
agentContent = await fs.readFile(filePath, 'utf8')
|
|
1070
|
+
break
|
|
1051
1071
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// If no agent file found, create one from manifest
|
|
1075
|
+
if (!agentFile) {
|
|
1076
|
+
const trigger = manifest.bmad?.activation_trigger || `@${agentId}`
|
|
1077
|
+
agentContent = `# ${manifest.name}
|
|
1078
|
+
|
|
1079
|
+
${manifest.tagline || manifest.description || ''}
|
|
1080
|
+
|
|
1081
|
+
## Activation
|
|
1082
|
+
|
|
1083
|
+
Use \`${trigger}\` in Cursor to activate this agent.
|
|
1084
|
+
|
|
1085
|
+
## Description
|
|
1086
|
+
|
|
1087
|
+
${manifest.long_description || manifest.description || 'NEX Agent'}
|
|
1058
1088
|
|
|
1059
|
-
|
|
1089
|
+
## Usage
|
|
1060
1090
|
|
|
1061
|
-
|
|
1091
|
+
\`\`\`
|
|
1092
|
+
${trigger} <command>
|
|
1093
|
+
\`\`\`
|
|
1062
1094
|
|
|
1063
|
-
|
|
1064
|
-
# ${trigger} <command>
|
|
1095
|
+
## Examples
|
|
1065
1096
|
|
|
1066
|
-
|
|
1067
|
-
# ${trigger} analyze-page https://example.com
|
|
1097
|
+
${trigger} analyze-page https://example.com
|
|
1068
1098
|
`
|
|
1069
|
-
|
|
1070
|
-
// Write basic rules file to agent directory
|
|
1071
|
-
await fs.writeFile(agentRulesPath, basicRules, 'utf8')
|
|
1072
|
-
console.log(chalk.cyan(`\n📝 Created basic Cursor rules file: ${rulesFile}`))
|
|
1073
|
-
} else {
|
|
1074
|
-
agentRulesPath = foundPath
|
|
1075
|
-
}
|
|
1076
1099
|
}
|
|
1077
1100
|
|
|
1078
|
-
//
|
|
1079
|
-
const
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
// Update main .cursorrules file (in project root)
|
|
1087
|
-
const mainCursorRulesPath = path.join(this.projectRoot, '.cursorrules')
|
|
1088
|
-
const importLine = `import .cursorrules/${rulesFile}`
|
|
1089
|
-
const commentLine = `# ${manifest.name} - ${manifest.tagline || manifest.description?.substring(0, 50)}`
|
|
1090
|
-
const agentTrigger = manifest.bmad?.activation_trigger || `@${agentId}`
|
|
1091
|
-
const agentComment = `# Use: ${agentTrigger} <command>`
|
|
1092
|
-
|
|
1093
|
-
let cursorRulesContent = ''
|
|
1094
|
-
if (await fs.pathExists(mainCursorRulesPath)) {
|
|
1095
|
-
cursorRulesContent = await fs.readFile(mainCursorRulesPath, 'utf8')
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
// Check if already imported
|
|
1099
|
-
if (cursorRulesContent.includes(importLine) || cursorRulesContent.includes(rulesFile)) {
|
|
1100
|
-
// Already integrated, skip
|
|
1101
|
-
return
|
|
1102
|
-
}
|
|
1101
|
+
// Convert to .mdc format (similar to BMAD)
|
|
1102
|
+
const mdcContent = `---
|
|
1103
|
+
description: ${manifest.name} - ${manifest.tagline || manifest.description?.substring(0, 100) || 'NEX Agent'}
|
|
1104
|
+
globs:
|
|
1105
|
+
alwaysApply: false
|
|
1106
|
+
---
|
|
1107
|
+
|
|
1108
|
+
${agentContent}`
|
|
1103
1109
|
|
|
1104
|
-
//
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1107
|
-
commentLine + '\n' +
|
|
1108
|
-
agentComment + '\n' +
|
|
1109
|
-
importLine + '\n'
|
|
1110
|
+
// Write .mdc file
|
|
1111
|
+
const mdcPath = path.join(agentRulesDir, `${agentId}.mdc`)
|
|
1112
|
+
await fs.writeFile(mdcPath, mdcContent, 'utf8')
|
|
1110
1113
|
|
|
1111
|
-
|
|
1114
|
+
// Update index.mdc (similar to BMAD index)
|
|
1115
|
+
await this.updateNexIndex(agentId, manifest, agentCategory)
|
|
1112
1116
|
|
|
1117
|
+
const agentTrigger = manifest.bmad?.activation_trigger || `@${agentId}`
|
|
1113
1118
|
console.log(chalk.green(`\n✅ Cursor integration complete!`))
|
|
1114
|
-
console.log(chalk.gray(`
|
|
1115
|
-
console.log(chalk.gray(` Use: ${agentTrigger}
|
|
1119
|
+
console.log(chalk.gray(` Agent installed in: .cursor/rules/nex/${agentCategory}/agents/${agentId}.mdc`))
|
|
1120
|
+
console.log(chalk.gray(` Use: ${agentTrigger} or @nex/${agentCategory}/agents/${agentId} in Cursor\n`))
|
|
1116
1121
|
|
|
1117
1122
|
} catch (error) {
|
|
1118
1123
|
console.log(chalk.yellow(`\n⚠️ Cursor integration failed: ${error.message}`))
|
|
@@ -1120,6 +1125,76 @@ export default class NEXMarketplace {
|
|
|
1120
1125
|
}
|
|
1121
1126
|
}
|
|
1122
1127
|
|
|
1128
|
+
/**
|
|
1129
|
+
* Update NEX index.mdc file (similar to BMAD index)
|
|
1130
|
+
*/
|
|
1131
|
+
async updateNexIndex(agentId, manifest, category) {
|
|
1132
|
+
const indexPath = path.join(this.projectRoot, '.cursor', 'rules', 'nex', 'index.mdc')
|
|
1133
|
+
const indexDir = path.dirname(indexPath)
|
|
1134
|
+
await fs.ensureDir(indexDir)
|
|
1135
|
+
|
|
1136
|
+
let indexContent = ''
|
|
1137
|
+
if (await fs.pathExists(indexPath)) {
|
|
1138
|
+
indexContent = await fs.readFile(indexPath, 'utf8')
|
|
1139
|
+
} else {
|
|
1140
|
+
// Create initial index
|
|
1141
|
+
indexContent = `---
|
|
1142
|
+
description: NEX Framework - Master Index
|
|
1143
|
+
globs:
|
|
1144
|
+
alwaysApply: true
|
|
1145
|
+
---
|
|
1146
|
+
|
|
1147
|
+
# NEX Framework - Cursor Rules Index
|
|
1148
|
+
|
|
1149
|
+
This is the master index for all NEX agents available in your project.
|
|
1150
|
+
|
|
1151
|
+
## Installation Complete!
|
|
1152
|
+
|
|
1153
|
+
NEX rules have been installed to: \`.cursor/rules/nex/\`
|
|
1154
|
+
|
|
1155
|
+
**Note:** NEX does not modify your \`.cursorrules\` file. You manage that separately.
|
|
1156
|
+
|
|
1157
|
+
## How to Use
|
|
1158
|
+
|
|
1159
|
+
- Reference specific agents: @nex/{category}/agents/{agent-name}
|
|
1160
|
+
- Reference this index: @nex/index
|
|
1161
|
+
|
|
1162
|
+
## Available Agents
|
|
1163
|
+
|
|
1164
|
+
`
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// Check if agent is already listed
|
|
1168
|
+
const agentRef = `@nex/${category}/agents/${agentId}`
|
|
1169
|
+
if (indexContent.includes(agentRef)) {
|
|
1170
|
+
return // Already listed
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
// Add agent to index
|
|
1174
|
+
const categorySection = `### ${category.toUpperCase()}\n\n**Agents:**\n`
|
|
1175
|
+
if (!indexContent.includes(categorySection)) {
|
|
1176
|
+
indexContent += categorySection
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
const agentEntry = `- ${agentRef} - ${manifest.name}\n`
|
|
1180
|
+
if (!indexContent.includes(agentEntry)) {
|
|
1181
|
+
// Find the category section and add agent
|
|
1182
|
+
const categoryIndex = indexContent.indexOf(`### ${category.toUpperCase()}`)
|
|
1183
|
+
if (categoryIndex !== -1) {
|
|
1184
|
+
const agentsIndex = indexContent.indexOf('**Agents:**', categoryIndex)
|
|
1185
|
+
if (agentsIndex !== -1) {
|
|
1186
|
+
const insertIndex = indexContent.indexOf('\n', agentsIndex) + 1
|
|
1187
|
+
indexContent = indexContent.slice(0, insertIndex) + agentEntry + indexContent.slice(insertIndex)
|
|
1188
|
+
}
|
|
1189
|
+
} else {
|
|
1190
|
+
// Category doesn't exist, add it
|
|
1191
|
+
indexContent += `### ${category.toUpperCase()}\n\n**Agents:**\n${agentEntry}\n\n`
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
await fs.writeFile(indexPath, indexContent, 'utf8')
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1123
1198
|
/**
|
|
1124
1199
|
* Get latest version of agent
|
|
1125
1200
|
*/
|