agentic-kdd 3.0.1 → 3.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/bin/akdd.js CHANGED
@@ -6,6 +6,7 @@ const { update } = require('../src/update');
6
6
  const { graph } = require('../src/graph');
7
7
  const { dashboard } = require('../src/dashboard');
8
8
  const { analyze } = require('../src/analyze');
9
+ const { mcpSetup, mcpStatus } = require('../src/mcp-setup');
9
10
  const pkg = require('../package.json');
10
11
  const path = require('path');
11
12
  const fs = require('fs');
@@ -73,9 +74,11 @@ const HELP = `
73
74
  Dashboard:
74
75
  akdd dashboard Open visual dashboard in browser
75
76
 
76
- MCP Server (Cursor / Claude Code):
77
- node .agentic/grafo/mcp-server.cjs
78
- See: github.com/Adrianlpz211/Agentic-KDD-MCP
77
+ MCP Setup (Cursor / Claude Code / VS Code):
78
+ akdd mcp Auto-configure MCP in all IDEs (recommended)
79
+ akdd mcp --global Configure MCP globally for all projects
80
+ akdd mcp status Check MCP configuration status
81
+ (manual fallback: imprime el JSON exacto con tu ruta real)
79
82
 
80
83
  akdd --version / akdd --help
81
84
  `;
@@ -242,6 +245,19 @@ switch (command) {
242
245
  break;
243
246
  }
244
247
 
248
+
249
+ // ── v3.0: MCP Setup ────────────────────────────────────────────────────
250
+ case 'mcp': {
251
+ const sub = arg1;
252
+ const opts = { global: args.includes('--global') };
253
+ if (sub === 'status') {
254
+ mcpStatus(process.cwd());
255
+ } else {
256
+ mcpSetup(process.cwd(), opts);
257
+ }
258
+ break;
259
+ }
260
+
245
261
  case '--version': case '-v':
246
262
  console.log(pkg.version); break;
247
263
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-kdd",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "Autonomous development pipeline — aa: · ag: · audit: · AST graph · Harness · Specs · Impact analysis · Decision trail · Metrics · MCP server. Works with Cursor and Claude Code.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/init.js CHANGED
@@ -1,4 +1,5 @@
1
1
  'use strict';
2
+ const { mcpSetup } = require('./mcp-setup');
2
3
 
3
4
  const fs = require('fs-extra');
4
5
  const path = require('path');
@@ -278,6 +279,14 @@ Estado: Pendiente aa: configurar
278
279
  console.log(chalk.gray(' CLAUDE.md — activa aa: / ag: / audit:'));
279
280
  console.log(chalk.gray(' .cursorrules — reglas para Cursor'));
280
281
 
282
+ // ── CONFIGURAR MCP AUTOMÁTICAMENTE ─────────────────────────────────────────
283
+ console.log(chalk.bold(" Configurando MCP server..."));
284
+ try {
285
+ await mcpSetup(projectPath, { silent: false });
286
+ } catch(e) {
287
+ console.log(chalk.gray(" (MCP: ejecuta akdd mcp para configurarlo manualmente)"));
288
+ }
289
+
281
290
  // Instrucción final
282
291
  console.log('\n' + chalk.dim(' ─────────────────────────────────────────────'));
283
292
  console.log(chalk.bold(' Último paso — abre este proyecto en'));
@@ -0,0 +1,265 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs-extra');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const { execSync } = require('child_process');
7
+ const chalk = require('chalk');
8
+
9
+ /**
10
+ * akdd mcp — Configura el MCP server automáticamente.
11
+ *
12
+ * Hace todo lo posible sin intervención del usuario:
13
+ * 1. Escribe .cursor/mcp.json en el proyecto (Cursor lo lee automáticamente)
14
+ * 2. Intenta ejecutar `claude mcp add` si el CLI está disponible
15
+ * 3. Imprime el JSON EXACTO (con ruta real del sistema, no placeholder)
16
+ * para los casos que requieran paso manual
17
+ *
18
+ * El usuario NUNCA tiene que adivinar la ruta — este comando la resuelve por él.
19
+ */
20
+
21
+ async function mcpSetup(projectPath, opts = {}) {
22
+ projectPath = projectPath || process.cwd();
23
+
24
+ // ── Verificar que Agentic está instalado ───────────────────────────────────
25
+ const serverFile = path.join(projectPath, '.agentic', 'grafo', 'mcp-server.cjs');
26
+ if (!fs.existsSync(serverFile)) {
27
+ console.log(chalk.yellow('\n mcp-server.cjs no encontrado.'));
28
+ console.log(chalk.gray(' Ejecuta: akdd update\n'));
29
+ return;
30
+ }
31
+
32
+ // ── Resolver ruta absoluta real (sin placeholders, sin adivinar) ───────────
33
+ // path.resolve() → ruta exacta del sistema actual, con nombre de usuario correcto
34
+ const serverPath = path.resolve(serverFile);
35
+ const serverPathJson = serverPath.replace(/\\/g, '\\\\'); // escaping para JSON en Windows
36
+
37
+ console.log('\n' + chalk.bold.hex('#8b5cf6')(' Agentic KDD — MCP Setup'));
38
+ console.log(chalk.gray(` Ruta del servidor: ${serverPath}\n`));
39
+
40
+ const results = {
41
+ cursor_project: false,
42
+ cursor_global: false,
43
+ claude_code: false,
44
+ };
45
+
46
+ // ══ PASO 1: Cursor — proyecto (automático, siempre funciona) ═══════════════
47
+ const cursorMcpDir = path.join(projectPath, '.cursor');
48
+ const cursorMcpFile = path.join(cursorMcpDir, 'mcp.json');
49
+
50
+ try {
51
+ fs.ensureDirSync(cursorMcpDir);
52
+
53
+ let cursorConfig = {};
54
+ if (fs.existsSync(cursorMcpFile)) {
55
+ try { cursorConfig = JSON.parse(fs.readFileSync(cursorMcpFile, 'utf8')); } catch {}
56
+ }
57
+ if (!cursorConfig.mcpServers) cursorConfig.mcpServers = {};
58
+
59
+ cursorConfig.mcpServers['agentic-kdd'] = {
60
+ command: 'node',
61
+ args: [serverPath],
62
+ };
63
+
64
+ fs.writeFileSync(cursorMcpFile, JSON.stringify(cursorConfig, null, 2));
65
+ results.cursor_project = true;
66
+ console.log(chalk.green(' ✓ Cursor (proyecto) → .cursor/mcp.json actualizado'));
67
+ console.log(chalk.gray(' Reinicia Cursor o recarga la ventana (Ctrl+Shift+P → "Reload Window")'));
68
+ } catch (e) {
69
+ console.log(chalk.yellow(` ⚠ Cursor (proyecto) → Error: ${e.message}`));
70
+ }
71
+
72
+ // ══ PASO 2: Claude Code CLI (automático si está instalado) ═════════════════
73
+ const claudeCliAvailable = isCLIAvailable('claude');
74
+ if (claudeCliAvailable) {
75
+ try {
76
+ // claude mcp add agentic-kdd -- node "/ruta/exacta/mcp-server.cjs"
77
+ execSync(`claude mcp add agentic-kdd -- node "${serverPath}"`, {
78
+ stdio: 'pipe',
79
+ cwd: projectPath,
80
+ });
81
+ results.claude_code = true;
82
+ console.log(chalk.green(' ✓ Claude Code → registrado via "claude mcp add"'));
83
+ } catch (e) {
84
+ // Puede fallar si ya existe — intentar actualizar
85
+ try {
86
+ execSync(`claude mcp remove agentic-kdd`, { stdio: 'pipe', cwd: projectPath });
87
+ execSync(`claude mcp add agentic-kdd -- node "${serverPath}"`, {
88
+ stdio: 'pipe', cwd: projectPath,
89
+ });
90
+ results.claude_code = true;
91
+ console.log(chalk.green(' ✓ Claude Code → actualizado'));
92
+ } catch {
93
+ console.log(chalk.gray(' ~ Claude Code → CLI no disponible o ya configurado'));
94
+ }
95
+ }
96
+ } else {
97
+ console.log(chalk.gray(' ~ Claude Code → CLI no detectado (config manual abajo)'));
98
+ }
99
+
100
+ // ══ PASO 3: Cursor global (opcional, solo si --global) ════════════════════
101
+ if (opts.global) {
102
+ const globalCursorConfig = getGlobalCursorConfigPath();
103
+ if (globalCursorConfig) {
104
+ try {
105
+ fs.ensureDirSync(path.dirname(globalCursorConfig));
106
+ let globalConfig = {};
107
+ if (fs.existsSync(globalCursorConfig)) {
108
+ try { globalConfig = JSON.parse(fs.readFileSync(globalCursorConfig, 'utf8')); } catch {}
109
+ }
110
+ if (!globalConfig.mcpServers) globalConfig.mcpServers = {};
111
+ globalConfig.mcpServers['agentic-kdd'] = { command: 'node', args: [serverPath] };
112
+ fs.writeFileSync(globalCursorConfig, JSON.stringify(globalConfig, null, 2));
113
+ results.cursor_global = true;
114
+ console.log(chalk.green(` ✓ Cursor (global) → ${globalCursorConfig}`));
115
+ } catch (e) {
116
+ console.log(chalk.yellow(` ⚠ Cursor (global) → ${e.message}`));
117
+ }
118
+ }
119
+ }
120
+
121
+ // ══ PASO 4: Imprimir configs manuales con ruta EXACTA ═════════════════════
122
+ console.log('\n' + chalk.bold(' ── Config manual (si necesitas hacerlo tú mismo) ──────────────────'));
123
+
124
+ // Cursor manual
125
+ const cursorJson = JSON.stringify({
126
+ mcpServers: {
127
+ 'agentic-kdd': {
128
+ command: 'node',
129
+ args: [serverPath],
130
+ }
131
+ }
132
+ }, null, 2);
133
+
134
+ console.log('\n' + chalk.cyan(' Cursor → .cursor/mcp.json'));
135
+ console.log(chalk.gray(' (Abre Cursor → Settings → MCP → Add → pega esto:)\n'));
136
+ console.log(chalk.white(cursorJson.split('\n').map(l => ' ' + l).join('\n')));
137
+
138
+ // Claude Code manual
139
+ console.log('\n' + chalk.cyan(' Claude Code → terminal'));
140
+ console.log(chalk.white(` claude mcp add agentic-kdd -- node "${serverPath}"`));
141
+
142
+ // VS Code manual
143
+ console.log('\n' + chalk.cyan(' VS Code → .vscode/settings.json'));
144
+ const vscodeJson = JSON.stringify({
145
+ 'mcp.servers': {
146
+ 'agentic-kdd': {
147
+ command: 'node',
148
+ args: [serverPath],
149
+ type: 'stdio',
150
+ }
151
+ }
152
+ }, null, 2);
153
+ console.log(chalk.white(vscodeJson.split('\n').map(l => ' ' + l).join('\n')));
154
+
155
+ // ══ RESUMEN ════════════════════════════════════════════════════════════════
156
+ console.log('\n' + chalk.dim(' ──────────────────────────────────────────────────────'));
157
+ const autoCount = Object.values(results).filter(Boolean).length;
158
+ if (autoCount > 0) {
159
+ console.log(chalk.bold.green(` ${autoCount} configuración(es) automática(s) completada(s).`));
160
+ }
161
+
162
+ if (results.cursor_project) {
163
+ console.log(chalk.green(' Cursor listo:') + chalk.gray(' Reload Window → las tools aparecen automáticamente.'));
164
+ }
165
+ if (results.claude_code) {
166
+ console.log(chalk.green(' Claude Code listo:') + chalk.gray(' cierra y abre el proyecto.'));
167
+ }
168
+
169
+ console.log('\n' + chalk.gray(' Para configurar globalmente (todos tus proyectos):'));
170
+ console.log(chalk.gray(' akdd mcp --global\n'));
171
+ }
172
+
173
+ // ─── HELPERS ──────────────────────────────────────────────────────────────────
174
+
175
+ function isCLIAvailable(cmd) {
176
+ try {
177
+ execSync(`${cmd} --version`, { stdio: 'pipe', timeout: 5000 });
178
+ return true;
179
+ } catch { return false; }
180
+ }
181
+
182
+ function getGlobalCursorConfigPath() {
183
+ const platform = os.platform();
184
+ const home = os.homedir();
185
+
186
+ if (platform === 'win32') {
187
+ // Windows: %APPDATA%\Cursor\User\globalStorage\mcp.json
188
+ const appData = process.env.APPDATA || path.join(home, 'AppData', 'Roaming');
189
+ return path.join(appData, 'Cursor', 'User', 'globalStorage', 'mcp.json');
190
+ }
191
+ if (platform === 'darwin') {
192
+ // macOS: ~/Library/Application Support/Cursor/User/globalStorage/mcp.json
193
+ return path.join(home, 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'mcp.json');
194
+ }
195
+ // Linux: ~/.config/Cursor/User/globalStorage/mcp.json
196
+ return path.join(home, '.config', 'Cursor', 'User', 'globalStorage', 'mcp.json');
197
+ }
198
+
199
+ /**
200
+ * Verifica y muestra el estado actual de la config MCP.
201
+ * akdd mcp status
202
+ */
203
+ function mcpStatus(projectPath) {
204
+ projectPath = projectPath || process.cwd();
205
+
206
+ const serverFile = path.join(projectPath, '.agentic', 'grafo', 'mcp-server.cjs');
207
+ const cursorProject = path.join(projectPath, '.cursor', 'mcp.json');
208
+ const globalCursor = getGlobalCursorConfigPath();
209
+
210
+ console.log('\n' + chalk.bold(' Agentic KDD — MCP Status\n'));
211
+
212
+ // Server file
213
+ const hasServer = fs.existsSync(serverFile);
214
+ console.log(hasServer
215
+ ? chalk.green(' ✓ mcp-server.cjs encontrado')
216
+ : chalk.red(' ✗ mcp-server.cjs NO encontrado — ejecutar: akdd update'));
217
+
218
+ // Cursor project config
219
+ let cursorProjectOk = false;
220
+ if (fs.existsSync(cursorProject)) {
221
+ try {
222
+ const config = JSON.parse(fs.readFileSync(cursorProject, 'utf8'));
223
+ cursorProjectOk = !!(config?.mcpServers?.['agentic-kdd']);
224
+ } catch {}
225
+ }
226
+ console.log(cursorProjectOk
227
+ ? chalk.green(' ✓ Cursor (proyecto) .cursor/mcp.json configurado')
228
+ : chalk.yellow(' ~ Cursor (proyecto) No configurado — ejecutar: akdd mcp'));
229
+
230
+ // Cursor global config
231
+ let cursorGlobalOk = false;
232
+ if (globalCursor && fs.existsSync(globalCursor)) {
233
+ try {
234
+ const config = JSON.parse(fs.readFileSync(globalCursor, 'utf8'));
235
+ cursorGlobalOk = !!(config?.mcpServers?.['agentic-kdd']);
236
+ } catch {}
237
+ }
238
+ console.log(cursorGlobalOk
239
+ ? chalk.green(' ✓ Cursor (global) configurado')
240
+ : chalk.gray(' ~ Cursor (global) No configurado — opcional: akdd mcp --global'));
241
+
242
+ // Claude Code
243
+ const claudeAvailable = isCLIAvailable('claude');
244
+ if (claudeAvailable) {
245
+ try {
246
+ const mcpList = execSync('claude mcp list', { stdio: 'pipe' }).toString();
247
+ const hasAgentic = mcpList.includes('agentic-kdd');
248
+ console.log(hasAgentic
249
+ ? chalk.green(' ✓ Claude Code registrado')
250
+ : chalk.yellow(' ~ Claude Code No registrado — ejecutar: akdd mcp'));
251
+ } catch {
252
+ console.log(chalk.gray(' ~ Claude Code CLI disponible pero sin listar MCPs'));
253
+ }
254
+ } else {
255
+ console.log(chalk.gray(' ~ Claude Code CLI No instalado'));
256
+ }
257
+
258
+ if (hasServer && !cursorProjectOk) {
259
+ console.log('\n' + chalk.bold(' → Ejecuta: akdd mcp\n'));
260
+ } else if (hasServer && cursorProjectOk) {
261
+ console.log('\n' + chalk.green(' Todo configurado. Recarga la ventana en Cursor si es necesario.\n'));
262
+ }
263
+ }
264
+
265
+ module.exports = { mcpSetup, mcpStatus };