@fernando.zavaleta/ai-platform-core 0.0.9-beta → 0.0.12-beta

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.
@@ -0,0 +1,49 @@
1
+ # Base Global Rules
2
+
3
+ Role:
4
+ You are a Senior AI Engineering Agent.
5
+
6
+ Language Policy:
7
+
8
+ - Internal framework configuration files must be written in ENGLISH.
9
+ - User-facing documentation and generated QA artifacts must be in SPANISH.
10
+
11
+ Execution Rules:
12
+
13
+ - NEVER create .py files unless explicitly asked.
14
+ - Prefer terminal commands (bash, curl, jq) for integrations.
15
+ - Always read credentials from:
16
+
17
+ 00-config/credentials.json
18
+
19
+ Output Rules:
20
+
21
+ - All generated artifacts must be Markdown (.md)
22
+ - Use professional Spanish
23
+ - QA outputs must be stored in:
24
+
25
+ 05-output/agente-qa/[JIRA_ID]/
26
+
27
+ # Artifact Policy
28
+
29
+ Agents may consume external data (JSON, API responses, logs).
30
+
31
+ However, intermediate data must not be stored in the repository output directories.
32
+
33
+ Only final documentation artifacts are allowed in:
34
+
35
+ 05-output/
36
+
37
+ Allowed formats:
38
+
39
+ .md
40
+
41
+ Disallowed formats:
42
+
43
+ .json
44
+ .log
45
+ .tmp
46
+
47
+ ## Interaction Rule
48
+ - Do not explain the plan unless explicitly asked.
49
+ - Execute the commands immediately and only report completion or critical errors.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qa-engineer",
3
- "version": "1.1.0",
3
+ "version": "0.0.1",
4
4
  "include_dirs": [
5
5
  "skills",
6
6
  "templates",
package/bin/cli.js CHANGED
@@ -4,21 +4,40 @@ const path = require('path');
4
4
 
5
5
  const profileKey = process.argv[2];
6
6
  const PACKAGE_ROOT = path.join(__dirname, '..');
7
- // Cambiamos la ruta para que incluya el nombre del perfil y mantenga orden
8
7
  const TARGET_BASE_DIR = path.join(process.cwd(), '.cursor', 'ai-platform', profileKey);
9
8
 
9
+ const USER_HOME = process.env.HOME || process.env.USERPROFILE;
10
+ const GLOBAL_CONFIG_DIR = path.join(USER_HOME, '.ai-platform');
11
+ const GLOBAL_CREDENTIALS_FILE = path.join(GLOBAL_CONFIG_DIR, 'credentials.json');
12
+
10
13
  const profiles = {
11
14
  "qa": "03.1-qa",
15
+ //"dev": "03.2-dev",
12
16
  "l3": "03.3-l3",
13
17
  "product": "03.4-product"
14
18
  };
15
19
 
16
20
  const domainFolder = profiles[profileKey];
17
21
  if (!domainFolder) {
18
- console.error("❌ Perfil no válido. Usa: qa, l3 o product");
22
+ console.error("❌ Perfil no válido. Usa: qa, dev, l3 o product");
19
23
  process.exit(1);
20
24
  }
21
25
 
26
+ if (!fs.existsSync(GLOBAL_CONFIG_DIR)) {
27
+ fs.mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
28
+ console.log(`📁 Carpeta de configuración creada en: ${GLOBAL_CONFIG_DIR}`);
29
+ }
30
+
31
+ if (!fs.existsSync(GLOBAL_CREDENTIALS_FILE)) {
32
+ const templateConfig = {
33
+ jira: { base_url: "https://jiracorp.belcorp.biz", pat_token: "TU_TOKEN" },
34
+ confluence: { base_url: "https://confluence.belcorp.biz", pat_token: "TU_TOKEN" },
35
+ sdp: { base_url: "https://sdp.belcorp.biz/api/v3", technician_key: "TU_TOKEN" }
36
+ };
37
+ fs.writeFileSync(GLOBAL_CREDENTIALS_FILE, JSON.stringify(templateConfig, null, 2));
38
+ console.log(`📝 Template de credenciales creado. Por favor, edita: ${GLOBAL_CREDENTIALS_FILE}`);
39
+ }
40
+
22
41
  const domainPath = path.join(PACKAGE_ROOT, '03-domains', domainFolder);
23
42
  const profileConfigPath = path.join(domainPath, 'profile.json');
24
43
 
@@ -29,7 +48,6 @@ if (!fs.existsSync(profileConfigPath)) {
29
48
 
30
49
  const config = JSON.parse(fs.readFileSync(profileConfigPath, 'utf8'));
31
50
 
32
- // Función para copiar carpetas completas manteniendo la estructura
33
51
  function copyRecursiveSync(src, dest) {
34
52
  const exists = fs.existsSync(src);
35
53
  const stats = exists && fs.statSync(src);
@@ -46,15 +64,13 @@ function copyRecursiveSync(src, dest) {
46
64
 
47
65
  console.log(`🚀 Instalando inteligencia estructurada para ${profileKey}...`);
48
66
 
49
- // 1. Proyectar el Agente (agent.md) si existe
50
67
  const agentFile = path.join(domainPath, 'agent.md');
51
68
  if (fs.existsSync(agentFile)) {
52
69
  if (!fs.existsSync(TARGET_BASE_DIR)) fs.mkdirSync(TARGET_BASE_DIR, { recursive: true });
53
70
  fs.copyFileSync(agentFile, path.join(TARGET_BASE_DIR, 'agent.md'));
54
- console.log(` 🤖 Agente proyectado en la raíz del perfil.`);
71
+ console.log(` 🤖 Agente proyectado.`);
55
72
  }
56
73
 
57
- // 2. Proyectar carpetas del profile.json manteniendo su jerarquía
58
74
  config.include_dirs.forEach(dirName => {
59
75
  const sourceDir = path.join(domainPath, dirName);
60
76
  const targetDir = path.join(TARGET_BASE_DIR, dirName);
@@ -65,5 +81,5 @@ config.include_dirs.forEach(dirName => {
65
81
  }
66
82
  });
67
83
 
68
- console.log(`\n✨ Perfil ${profileKey} instalado en .cursor/ai-platform/${profileKey}`);
69
- console.log(`💡 Ahora puedes referenciar al agente con @agent.md desde esa carpeta.`);
84
+ console.log(`\n✨ Perfil ${profileKey} listo.`);
85
+ console.log(`👉 Configura el MCP en Cursor usando: ${GLOBAL_CREDENTIALS_FILE}`);
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env node
2
+ const { Server } = require("@modelcontextprotocol/sdk/server/index.js");
3
+ const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");
4
+ const { CallToolRequestSchema, ListToolsRequestSchema } = require("@modelcontextprotocol/sdk/types.js");
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const axios = require('axios');
8
+
9
+ function loadCredentials() {
10
+ const envPath = process.env.AI_PLATFORM_CREDENTIALS;
11
+ const defaultPath = path.join(process.env.HOME || process.env.USERPROFILE, '.ai-platform', 'credentials.json');
12
+
13
+ const configPath = envPath || defaultPath;
14
+
15
+ if (!fs.existsSync(configPath)) {
16
+ console.error(`❌ Error: No se encontró credentials.json en ${configPath}`);
17
+ process.exit(1);
18
+ }
19
+
20
+ try {
21
+ return JSON.parse(fs.readFileSync(configPath, 'utf8'));
22
+ } catch (error) {
23
+ console.error("❌ Error al parsear credentials.json:", error.message);
24
+ process.exit(1);
25
+ }
26
+ }
27
+
28
+ const credentials = loadCredentials();
29
+
30
+ const server = new Server({
31
+ name: "tismart-belcorp-bridge",
32
+ version: "0.0.12-beta"
33
+ }, {
34
+ capabilities: { tools: {} }
35
+ });
36
+
37
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
38
+ tools: [
39
+ {
40
+ name: "get_jira_ticket",
41
+ description: "Consulta un ticket en el Jira de Belcorp para obtener resumen, descripción y estado.",
42
+ inputSchema: {
43
+ type: "object",
44
+ properties: {
45
+ issueKey: { type: "string", description: "ID del ticket (ej: QA-123)" }
46
+ },
47
+ required: ["issueKey"]
48
+ }
49
+ },
50
+ {
51
+ name: "get_sdp_request",
52
+ description: "Obtiene los detalles de un requerimiento en Service Desk Plus (SDP) de Belcorp.",
53
+ inputSchema: {
54
+ type: "object",
55
+ properties: {
56
+ requestId: { type: "string", description: "ID numérico de la solicitud" }
57
+ },
58
+ required: ["requestId"]
59
+ }
60
+ },
61
+ {
62
+ name: "search_confluence_rca",
63
+ description: "Realiza una búsqueda semántica de RCAs o documentos en Confluence Belcorp.",
64
+ inputSchema: {
65
+ type: "object",
66
+ properties: {
67
+ query: { type: "string", description: "Término de búsqueda" }
68
+ },
69
+ required: ["query"]
70
+ }
71
+ }
72
+ ]
73
+ }));
74
+
75
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
76
+ const { name, arguments: args } = request.params;
77
+
78
+ try {
79
+ switch (name) {
80
+ case "get_jira_ticket": {
81
+ const url = `${credentials.jira.base_url}/rest/api/2/issue/${args.issueKey}`;
82
+ const response = await axios.get(url, {
83
+ headers: {
84
+ 'Authorization': `Bearer ${credentials.jira.pat_token}`,
85
+ 'Content-Type': 'application/json'
86
+ }
87
+ });
88
+ return {
89
+ content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }]
90
+ };
91
+ }
92
+
93
+ case "get_sdp_request": {
94
+ const url = `${credentials.sdp.base_url}/requests/${args.requestId}`;
95
+ const response = await axios.get(url, {
96
+ headers: {
97
+ 'technician_key': credentials.sdp.technician_key,
98
+ 'Content-Type': 'application/json'
99
+ }
100
+ });
101
+ return {
102
+ content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }]
103
+ };
104
+ }
105
+
106
+ case "search_confluence_rca": {
107
+ const url = `${credentials.confluence.base_url}/rest/api/content/search?cql=text ~ "${args.query}"`;
108
+ const response = await axios.get(url, {
109
+ headers: {
110
+ 'Authorization': `Bearer ${credentials.confluence.pat_token}`,
111
+ 'Content-Type': 'application/json'
112
+ }
113
+ });
114
+ return {
115
+ content: [{ type: "text", text: JSON.stringify(response.data.results, null, 2) }]
116
+ };
117
+ }
118
+
119
+ default:
120
+ throw new Error(`Herramienta no reconocida: ${name}`);
121
+ }
122
+ } catch (error) {
123
+ return {
124
+ isError: true,
125
+ content: [{
126
+ type: "text",
127
+ text: `Error en Belcorp Bridge [${name}]: ${error.response?.data?.errorMessages?.[0] || error.message}`
128
+ }]
129
+ };
130
+ }
131
+ });
132
+
133
+ async function main() {
134
+ const transport = new StdioServerTransport();
135
+ await server.connect(transport);
136
+ console.error("🚀 MCP Server de Belcorp iniciado correctamente.");
137
+ }
138
+
139
+ main().catch(console.error);
package/package.json CHANGED
@@ -1,18 +1,23 @@
1
1
  {
2
2
  "name": "@fernando.zavaleta/ai-platform-core",
3
- "version": "0.0.9-beta",
3
+ "version": "0.0.12-beta",
4
4
  "description": "Enterprise AI Framework Distribution Tool",
5
5
  "main": "index.js",
6
6
  "bin": {
7
- "ia-install": "./bin/cli.js"
7
+ "ia-install": "./bin/cli.js",
8
+ "ia-mcp": "./bin/mcp-server.js"
8
9
  },
9
10
  "files": [
10
11
  "03-domains",
11
12
  "02-mcp",
12
- "00-config/global-base.md",
13
+ "01-rules/global-base.md",
13
14
  "bin"
14
15
  ],
15
16
  "scripts": {
16
17
  "test": "echo \"Error: no test specified\" && exit 1"
18
+ },
19
+ "dependencies": {
20
+ "@modelcontextprotocol/sdk": "^1.27.1",
21
+ "axios": "^1.13.6"
17
22
  }
18
23
  }