@christianmaf80/agentic-workflow 1.3.0-beta.1 → 1.5.0-beta.1
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/cli.js +0 -13
- package/dist/cli/commands/init.js +0 -17
- package/dist/core/context/manager.js +5 -31
- package/dist/workflows/init.md +6 -8
- package/package.json +2 -3
- package/dist/cli/commands/mcp-register.js +0 -33
- package/dist/mcp/server.js +0 -218
package/bin/cli.js
CHANGED
|
@@ -3,8 +3,6 @@ import { Command } from 'commander';
|
|
|
3
3
|
import { initCommand } from '../dist/cli/commands/init.js';
|
|
4
4
|
import { createCommand } from '../dist/cli/commands/create.js';
|
|
5
5
|
import { restoreCommand } from '../dist/cli/commands/restore.js';
|
|
6
|
-
import { runMcpServer } from '../dist/mcp/server.js';
|
|
7
|
-
import { registerMcpCommand } from '../dist/cli/commands/mcp-register.js';
|
|
8
6
|
|
|
9
7
|
const program = new Command();
|
|
10
8
|
|
|
@@ -25,17 +23,6 @@ program
|
|
|
25
23
|
.description('Scaffold a new project-specific element')
|
|
26
24
|
.action(createCommand);
|
|
27
25
|
|
|
28
|
-
program
|
|
29
|
-
.command('mcp')
|
|
30
|
-
.description('Start the Model Context Protocol (MCP) server')
|
|
31
|
-
.action(runMcpServer);
|
|
32
|
-
|
|
33
|
-
program
|
|
34
|
-
.command('mcp:register')
|
|
35
|
-
.description('Register the MCP server in a config file')
|
|
36
|
-
.option('--path <path>', 'Write to a specific MCP config path (required)')
|
|
37
|
-
.action(registerMcpCommand);
|
|
38
|
-
|
|
39
26
|
program
|
|
40
27
|
.command('restore')
|
|
41
28
|
.description('Restore the agentic system from a backup')
|
|
@@ -121,23 +121,6 @@ The core rules reside at:
|
|
|
121
121
|
- \`${path.join(corePath, 'rules/index.md')}\`
|
|
122
122
|
`;
|
|
123
123
|
await fs.writeFile(path.join(cwd, 'AGENTS.md'), agentsMdContent);
|
|
124
|
-
// 5. Create MCP Configuration for Antigravity/IDE
|
|
125
|
-
const sMcp = spinner();
|
|
126
|
-
sMcp.start('Configuring MCP Server for IDE...');
|
|
127
|
-
const mcpConfigDir = path.join(cwd, '.antigravity');
|
|
128
|
-
await fs.mkdir(mcpConfigDir, { recursive: true });
|
|
129
|
-
const mcpConfig = {
|
|
130
|
-
mcpServers: {
|
|
131
|
-
"agentic-workflow": {
|
|
132
|
-
command: "node",
|
|
133
|
-
args: [path.join(corePath, '../bin/cli.js'), "mcp"],
|
|
134
|
-
env: {},
|
|
135
|
-
disabled: false
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
await fs.writeFile(path.join(mcpConfigDir, 'task_mcp_config.json'), JSON.stringify(mcpConfig, null, 2));
|
|
140
|
-
sMcp.stop('MCP Server configured (.antigravity/task_mcp_config.json)');
|
|
141
124
|
s.stop('Configuration complete.');
|
|
142
125
|
note(`Core located at: ${corePath}\nAbsolute references have been configured for the IDE.`, 'Architecture by Reference');
|
|
143
126
|
outro('Agentic System initialized successfully\nYour core is now protected in node_modules.');
|
|
@@ -66,39 +66,13 @@ export class ContextManager {
|
|
|
66
66
|
if (await this.exists(localTemplatesIndex))
|
|
67
67
|
files.push(await this.readFile(localTemplatesIndex, 'agent.local.templates'));
|
|
68
68
|
const localBundle = this.formatBundle(files, true);
|
|
69
|
-
//
|
|
69
|
+
// Use prebuilt core bootstrap bundle only (no dynamic fallback).
|
|
70
70
|
const coreBootstrapPath = path.join(this.corePath, 'bootstrap.md');
|
|
71
|
-
if (await this.exists(coreBootstrapPath)) {
|
|
72
|
-
|
|
73
|
-
return `${localBundle}\n\n---\n\n${coreBundle}`.trim();
|
|
71
|
+
if (!(await this.exists(coreBootstrapPath))) {
|
|
72
|
+
throw new Error('No se encontró bootstrap.md en el core. Ejecuta el build para generarlo.');
|
|
74
73
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const coreWorkflowsIndex = path.join(this.corePath, 'workflows/index.md');
|
|
78
|
-
const coreTemplatesIndex = path.join(this.corePath, 'templates/index.md');
|
|
79
|
-
const coreArtifactsIndex = path.join(this.corePath, 'artifacts/index.md');
|
|
80
|
-
if (await this.exists(coreRulesIndex))
|
|
81
|
-
files.push(await this.readFile(coreRulesIndex, 'agent.core.rules'));
|
|
82
|
-
if (await this.exists(coreWorkflowsIndex))
|
|
83
|
-
files.push(await this.readFile(coreWorkflowsIndex, 'agent.core.workflows'));
|
|
84
|
-
if (await this.exists(coreTemplatesIndex))
|
|
85
|
-
files.push(await this.readFile(coreTemplatesIndex, 'agent.core.templates'));
|
|
86
|
-
if (await this.exists(coreArtifactsIndex))
|
|
87
|
-
files.push(await this.readFile(coreArtifactsIndex, 'agent.core.artifacts'));
|
|
88
|
-
// 4. Constituciones Críticas
|
|
89
|
-
const constitutions = ['GEMINI.location.md', 'project-architecture.md', 'clean-code.md', 'agent-system.md'];
|
|
90
|
-
for (const c of constitutions) {
|
|
91
|
-
const p = path.join(this.corePath, 'rules/constitution', c);
|
|
92
|
-
if (await this.exists(p)) {
|
|
93
|
-
files.push(await this.readFile(p, `constitution.${c.replace('.md', '')}`));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
// 5. Rol Arquitecto
|
|
97
|
-
const archRole = path.join(this.corePath, 'rules/roles/architect.md');
|
|
98
|
-
if (await this.exists(archRole)) {
|
|
99
|
-
files.push(await this.readFile(archRole, 'roles.architect'));
|
|
100
|
-
}
|
|
101
|
-
return this.formatBundle(files, true);
|
|
74
|
+
const coreBundle = await fs.readFile(coreBootstrapPath, 'utf-8');
|
|
75
|
+
return `${localBundle}\n\n---\n\n${coreBundle}`.trim();
|
|
102
76
|
}
|
|
103
77
|
async readFile(filePath, alias) {
|
|
104
78
|
const content = await fs.readFile(filePath, 'utf-8');
|
package/dist/workflows/init.md
CHANGED
|
@@ -28,14 +28,12 @@ blocking: true
|
|
|
28
28
|
## Mandatory Steps
|
|
29
29
|
1. **Reasoning (MANDATORY)**
|
|
30
30
|
- Explain to the developer what will be done in this phase and why.
|
|
31
|
-
2. Use the `bootstrap_context` tool to load
|
|
32
|
-
3.
|
|
33
|
-
4.
|
|
34
|
-
5.
|
|
35
|
-
6.
|
|
36
|
-
7.
|
|
37
|
-
8. Create the `init.md` artifact using `templates.init`.
|
|
38
|
-
9. Evaluate Gate.
|
|
31
|
+
2. Use the `bootstrap_context` tool to load the prebuilt core bootstrap bundle plus local indices in a single step.
|
|
32
|
+
3. Save the bundle output to `.agent/artifacts/candidate/bootstrap.md`.
|
|
33
|
+
4. Detect preferred language and ask for explicit confirmation (**YES**).
|
|
34
|
+
5. Select lifecycle strategy (**Long** or **Short**).
|
|
35
|
+
6. Create the `init.md` artifact using `templates.init`.
|
|
36
|
+
7. Evaluate Gate.
|
|
39
37
|
- The developer **MUST** explicitly confirm with a **YES**.
|
|
40
38
|
|
|
41
39
|
## Output (REQUIRED)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@christianmaf80/agentic-workflow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0-beta.1",
|
|
4
4
|
"description": "Portable agentic workflow orchestration system with strict identity and gate discipline",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,10 +14,9 @@
|
|
|
14
14
|
"LICENSE"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "tsc && npm run copy-assets && node scripts/build-bootstrap.mjs",
|
|
17
|
+
"build": "node scripts/clean-dist.mjs && tsc && npm run copy-assets && node scripts/build-bootstrap.mjs",
|
|
18
18
|
"copy-assets": "cp -r src/rules src/workflows src/templates src/artifacts dist/",
|
|
19
19
|
"start": "node dist/index.js",
|
|
20
|
-
"mcp": "node bin/cli.js mcp",
|
|
21
20
|
"publish:npm": "npm publish --registry https://registry.npmjs.org --access public",
|
|
22
21
|
"publish:github": "npm publish --registry https://npm.pkg.github.com"
|
|
23
22
|
},
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { resolveCorePath, resolveInstalledCorePath } from '../../core/mapping/resolver.js';
|
|
4
|
-
export async function registerMcpCommand(options) {
|
|
5
|
-
if (!options.path) {
|
|
6
|
-
throw new Error('Missing --path. Provide the full path to the MCP config file.');
|
|
7
|
-
}
|
|
8
|
-
const configPath = options.path;
|
|
9
|
-
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
10
|
-
const config = await readConfig(configPath);
|
|
11
|
-
config.mcpServers = config.mcpServers ?? {};
|
|
12
|
-
const corePath = (await resolveInstalledCorePath(process.cwd())) ?? await resolveCorePath();
|
|
13
|
-
const binPath = path.join(corePath, '../bin/cli.js');
|
|
14
|
-
config.mcpServers['agentic-workflow'] = {
|
|
15
|
-
command: 'node',
|
|
16
|
-
args: [binPath, 'mcp'],
|
|
17
|
-
env: {},
|
|
18
|
-
disabled: false
|
|
19
|
-
};
|
|
20
|
-
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
21
|
-
// eslint-disable-next-line no-console
|
|
22
|
-
console.log(`MCP server registered at: ${configPath}`);
|
|
23
|
-
}
|
|
24
|
-
async function readConfig(configPath) {
|
|
25
|
-
try {
|
|
26
|
-
const raw = await fs.readFile(configPath, 'utf-8');
|
|
27
|
-
const parsed = JSON.parse(raw);
|
|
28
|
-
return typeof parsed === 'object' && parsed !== null ? parsed : {};
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return {};
|
|
32
|
-
}
|
|
33
|
-
}
|
package/dist/mcp/server.js
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
-
import { execFile } from "node:child_process";
|
|
5
|
-
import path from "node:path";
|
|
6
|
-
import { performCreate } from "../cli/commands/create.js";
|
|
7
|
-
import { ContextManager } from "../core/context/manager.js";
|
|
8
|
-
import { resolveCorePath, resolveInstalledCorePath } from "../core/mapping/resolver.js";
|
|
9
|
-
/**
|
|
10
|
-
* Servidor MCP para el framework Agentic Workflow.
|
|
11
|
-
* Proporciona herramientas estructuradas para extender el sistema.
|
|
12
|
-
*/
|
|
13
|
-
export async function runMcpServer() {
|
|
14
|
-
const server = new Server({
|
|
15
|
-
name: "agentic-workflow-server",
|
|
16
|
-
version: "1.3.0",
|
|
17
|
-
}, {
|
|
18
|
-
capabilities: {
|
|
19
|
-
tools: {},
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
// Configuración del Ciclo de Vida (Lifecycle)
|
|
23
|
-
const INACTIVITY_TIMEOUT = 30 * 60 * 1000; // 30 minutos
|
|
24
|
-
let inactivityTimer;
|
|
25
|
-
const projectRoot = process.cwd();
|
|
26
|
-
const allowedCommands = new Set(["cat", "ls", "rg", "sed", "head", "tail", "pwd"]);
|
|
27
|
-
const resetInactivityTimer = () => {
|
|
28
|
-
if (inactivityTimer)
|
|
29
|
-
clearTimeout(inactivityTimer);
|
|
30
|
-
inactivityTimer = setTimeout(() => {
|
|
31
|
-
console.error("MCP Server shutting down due to inactivity...");
|
|
32
|
-
process.exit(0);
|
|
33
|
-
}, INACTIVITY_TIMEOUT);
|
|
34
|
-
};
|
|
35
|
-
// Iniciar timer inicial
|
|
36
|
-
resetInactivityTimer();
|
|
37
|
-
/**
|
|
38
|
-
* Listado de herramientas disponibles.
|
|
39
|
-
*/
|
|
40
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
41
|
-
resetInactivityTimer();
|
|
42
|
-
return {
|
|
43
|
-
tools: [
|
|
44
|
-
{
|
|
45
|
-
name: "create_role",
|
|
46
|
-
description: "Crea un nuevo rol (agente) en el proyecto local bajo la carpeta espejo .agent/roles/.",
|
|
47
|
-
inputSchema: {
|
|
48
|
-
type: "object",
|
|
49
|
-
properties: {
|
|
50
|
-
name: {
|
|
51
|
-
type: "string",
|
|
52
|
-
description: "Nombre del rol (ej: devops, qa, reviewer)",
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
required: ["name"],
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
name: "create_workflow",
|
|
60
|
-
description: "Crea un nuevo workflow personalizado en el proyecto local bajo la carpeta espejo .agent/workflows/.",
|
|
61
|
-
inputSchema: {
|
|
62
|
-
type: "object",
|
|
63
|
-
properties: {
|
|
64
|
-
name: {
|
|
65
|
-
type: "string",
|
|
66
|
-
description: "Nombre del workflow (ej: refactor, release, triage)",
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
required: ["name"],
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
name: "bootstrap_context",
|
|
74
|
-
description: "Genera un bundle consolidado con el índice maestro, índices de dominio, constitución base y roles esenciales en un solo paso (Best Practice).",
|
|
75
|
-
inputSchema: {
|
|
76
|
-
type: "object",
|
|
77
|
-
properties: {},
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
name: "hydrate_context",
|
|
82
|
-
description: "Carga dinámicamente el contenido de todos los ficheros asociados a un alias (ej: rules.constitution) de forma consolidada.",
|
|
83
|
-
inputSchema: {
|
|
84
|
-
type: "object",
|
|
85
|
-
properties: {
|
|
86
|
-
alias: {
|
|
87
|
-
type: "string",
|
|
88
|
-
description: "Alias del dominio a hidratar (ej: rules.constitution, workflows.modules)",
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
required: ["alias"],
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
name: "stop_server",
|
|
96
|
-
description: "Detiene el servidor MCP inmediatamente.",
|
|
97
|
-
inputSchema: {
|
|
98
|
-
type: "object",
|
|
99
|
-
properties: {},
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
name: "run_command",
|
|
104
|
-
description: "Ejecuta comandos de lectura seguros dentro del proyecto (cat/ls/rg/sed/head/tail/pwd).",
|
|
105
|
-
inputSchema: {
|
|
106
|
-
type: "object",
|
|
107
|
-
properties: {
|
|
108
|
-
command: {
|
|
109
|
-
type: "string",
|
|
110
|
-
description: "Comando a ejecutar (ej: cat, rg, ls).",
|
|
111
|
-
},
|
|
112
|
-
args: {
|
|
113
|
-
type: "array",
|
|
114
|
-
items: { type: "string" },
|
|
115
|
-
description: "Argumentos del comando.",
|
|
116
|
-
},
|
|
117
|
-
cwd: {
|
|
118
|
-
type: "string",
|
|
119
|
-
description: "Directorio de trabajo relativo al proyecto (opcional).",
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
required: ["command"],
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
};
|
|
127
|
-
});
|
|
128
|
-
/**
|
|
129
|
-
* Manejador de llamadas a herramientas.
|
|
130
|
-
*/
|
|
131
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
132
|
-
resetInactivityTimer();
|
|
133
|
-
const { name, arguments: args } = request.params;
|
|
134
|
-
if (name === "create_role" || name === "create_workflow") {
|
|
135
|
-
const type = name === "create_role" ? "role" : "workflow";
|
|
136
|
-
const entityName = args.name;
|
|
137
|
-
if (!entityName) {
|
|
138
|
-
throw new Error("El nombre de la entidad es obligatorio.");
|
|
139
|
-
}
|
|
140
|
-
const result = await performCreate(type, entityName);
|
|
141
|
-
return {
|
|
142
|
-
content: [
|
|
143
|
-
{
|
|
144
|
-
type: "text",
|
|
145
|
-
text: result.message,
|
|
146
|
-
},
|
|
147
|
-
],
|
|
148
|
-
isError: !result.success,
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
if (name === "bootstrap_context") {
|
|
152
|
-
const corePath = (await resolveInstalledCorePath(projectRoot)) ?? await resolveCorePath();
|
|
153
|
-
const manager = new ContextManager(process.cwd(), corePath);
|
|
154
|
-
const bundle = await manager.bootstrapContext();
|
|
155
|
-
return {
|
|
156
|
-
content: [{ type: "text", text: bundle }]
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
if (name === "hydrate_context") {
|
|
160
|
-
const corePath = (await resolveInstalledCorePath(projectRoot)) ?? await resolveCorePath();
|
|
161
|
-
const manager = new ContextManager(process.cwd(), corePath);
|
|
162
|
-
const alias = args.alias;
|
|
163
|
-
const files = await manager.resolveAlias(alias);
|
|
164
|
-
if (files.length === 0) {
|
|
165
|
-
return {
|
|
166
|
-
content: [{ type: "text", text: `No se encontraron ficheros para el alias: ${alias}` }],
|
|
167
|
-
isError: true
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
const bundle = manager.formatBundle(files);
|
|
171
|
-
return {
|
|
172
|
-
content: [{ type: "text", text: bundle }]
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
if (name === "run_command") {
|
|
176
|
-
const { command, args: cmdArgs, cwd } = args;
|
|
177
|
-
if (!command) {
|
|
178
|
-
throw new Error("El comando es obligatorio.");
|
|
179
|
-
}
|
|
180
|
-
const baseCommand = path.basename(command);
|
|
181
|
-
if (!allowedCommands.has(baseCommand)) {
|
|
182
|
-
throw new Error(`Comando no permitido: ${baseCommand}`);
|
|
183
|
-
}
|
|
184
|
-
const resolvedCwd = cwd ? path.resolve(projectRoot, cwd) : projectRoot;
|
|
185
|
-
if (!resolvedCwd.startsWith(projectRoot)) {
|
|
186
|
-
throw new Error("El cwd debe estar dentro del proyecto.");
|
|
187
|
-
}
|
|
188
|
-
const output = await execFileAsync(baseCommand, Array.isArray(cmdArgs) ? cmdArgs : [], resolvedCwd);
|
|
189
|
-
return {
|
|
190
|
-
content: [{ type: "text", text: output }],
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
if (name === "stop_server") {
|
|
194
|
-
setTimeout(() => process.exit(0), 100);
|
|
195
|
-
return {
|
|
196
|
-
content: [{ type: "text", text: "Servidor deteniéndose..." }]
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
throw new Error(`Herramienta no encontrada: ${name}`);
|
|
200
|
-
});
|
|
201
|
-
// Conexión mediante Standard Input/Output (Stdio)
|
|
202
|
-
const transport = new StdioServerTransport();
|
|
203
|
-
await server.connect(transport);
|
|
204
|
-
console.error("Agentic Workflow MCP Server running on stdio");
|
|
205
|
-
}
|
|
206
|
-
function execFileAsync(command, args, cwd) {
|
|
207
|
-
return new Promise((resolve, reject) => {
|
|
208
|
-
execFile(command, args, { cwd, maxBuffer: 1024 * 1024 }, (error, stdout, stderr) => {
|
|
209
|
-
if (error) {
|
|
210
|
-
const message = stderr?.trim() || error.message || "Error ejecutando comando.";
|
|
211
|
-
reject(new Error(message));
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
const output = `${stdout ?? ""}${stderr ?? ""}`.trim();
|
|
215
|
-
resolve(output.length > 0 ? output : "(sin salida)");
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
}
|