create-gru 0.1.0
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/README.md +95 -0
- package/index.mjs +198 -0
- package/package.json +37 -0
- package/template/.claude/CLAUDE.md +541 -0
- package/template/.claude/agents/arch.agent.md +207 -0
- package/template/.claude/agents/caveman-mode.agent.md +32 -0
- package/template/.claude/agents/critical-thinking.agent.md +25 -0
- package/template/.claude/agents/cybersec/blueteam-coordinator.agent.md +46 -0
- package/template/.claude/agents/cybersec/blueteam-detect.agent.md +44 -0
- package/template/.claude/agents/cybersec/blueteam-hardening.agent.md +45 -0
- package/template/.claude/agents/cybersec/blueteam-incident.agent.md +46 -0
- package/template/.claude/agents/cybersec/purpleteam-coordinator.agent.md +52 -0
- package/template/.claude/agents/cybersec/redteam-coordinator.agent.md +51 -0
- package/template/.claude/agents/cybersec/redteam-exploit.agent.md +47 -0
- package/template/.claude/agents/cybersec/redteam-recon.agent.md +46 -0
- package/template/.claude/agents/devils-advocate.agent.md +43 -0
- package/template/.claude/agents/gem-orchestrator.agent.md +502 -0
- package/template/.claude/agents/jd-fix-agent.md +21 -0
- package/template/.claude/agents/jd-judge-a.md +19 -0
- package/template/.claude/agents/jd-judge-b.md +19 -0
- package/template/.claude/agents/plan.agent.md +134 -0
- package/template/.claude/agents/rug-orchestrator.agent.md +225 -0
- package/template/.claude/agents/sast-sca-security-analyzer.agent.md +402 -0
- package/template/.claude/agents/sdd-apply.md +49 -0
- package/template/.claude/agents/sdd-archive.md +48 -0
- package/template/.claude/agents/sdd-design.md +45 -0
- package/template/.claude/agents/sdd-explore.md +45 -0
- package/template/.claude/agents/sdd-init.md +42 -0
- package/template/.claude/agents/sdd-onboard.md +42 -0
- package/template/.claude/agents/sdd-propose.md +58 -0
- package/template/.claude/agents/sdd-spec.md +44 -0
- package/template/.claude/agents/sdd-tasks.md +45 -0
- package/template/.claude/agents/sdd-verify.md +44 -0
- package/template/.claude/agents/specification.agent.md +129 -0
- package/template/.claude/output-styles/gru.md +102 -0
- package/template/.mcp.json +42 -0
- package/template/SDD.md +308 -0
- package/template/cybersec-minion-contract.md +114 -0
- package/template/minion-contract.md +166 -0
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# create-gru
|
|
2
|
+
|
|
3
|
+
Instalador del **harness Gru** (modo B) para cualquier proyecto. Cero dependencias.
|
|
4
|
+
|
|
5
|
+
Gru es una capa de orquestación de LLMs: clasifica cada tarea por complejidad y
|
|
6
|
+
riesgo, exige aprobación humana en lo destructivo y delega la ejecución en
|
|
7
|
+
*providers* especializados. Este paquete solo **copia los archivos de
|
|
8
|
+
instrucciones del harness** (persona, contratos de minions, config MCP y los
|
|
9
|
+
agentes Gru-nativos) a tu proyecto. No ejecuta nada por sí mismo.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm dlx create-gru init # interactivo, en el directorio actual
|
|
13
|
+
pnpm dlx create-gru init ./mi-proyecto # destino explícito
|
|
14
|
+
pnpm dlx create-gru init --yes # sin preguntar (perfil recomendado)
|
|
15
|
+
pnpm dlx create-gru init --minimal # solo CLAUDE.md + minion-contract.md
|
|
16
|
+
pnpm dlx create-gru init --force # sobrescribe (copia por archivo, hace merge)
|
|
17
|
+
pnpm dlx create-gru init --dry-run # muestra qué haría, sin escribir
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Con TTY pregunta grupo por grupo. Sin TTY (CI) usa el perfil recomendado. La
|
|
21
|
+
copia es **por archivo**: respeta tus archivos existentes y añade los que falten.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## ⚠️ Aviso de uso
|
|
26
|
+
|
|
27
|
+
**Este paquete es para uso propio, no para comercialización.**
|
|
28
|
+
|
|
29
|
+
`create-gru` y el harness Gru son un proyecto personal. Se distribuye tal cual,
|
|
30
|
+
sin garantía, y **no está destinado a la venta ni a uso comercial**. Orquesta
|
|
31
|
+
herramientas de terceros que mantienen sus propios autores y licencias: el uso
|
|
32
|
+
de cada una se rige por la licencia de su repositorio de origen. Respeta esas
|
|
33
|
+
licencias. Los nombres y marcas de cada proyecto pertenecen a sus autores.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Providers que orquesta el harness
|
|
38
|
+
|
|
39
|
+
Gru no incluye estos providers; los **invoca** si están instalados. Cada uno es
|
|
40
|
+
un proyecto independiente con su propio repositorio y licencia:
|
|
41
|
+
|
|
42
|
+
| Provider | Rol en Gru | Instalación | Repositorio / fuente |
|
|
43
|
+
| :--- | :--- | :--- | :--- |
|
|
44
|
+
| **pnpm** | Gestor de paquetes / runner | `corepack enable` · `npm i -g pnpm` | https://github.com/pnpm/pnpm |
|
|
45
|
+
| **pi** | Runtime de Gentle-Pi | `npm install -g pi` | https://www.npmjs.com/package/pi |
|
|
46
|
+
| **gentle-pi** | Especificación SDD/OpenSpec y TDD | `pi install npm:gentle-pi` | https://www.npmjs.com/package/gentle-pi |
|
|
47
|
+
| **gentle-ai** (gentlemanCli) | Diagnóstico de entorno y sync de skills | instalador oficial | https://github.com/Gentleman-Programming/gentle-ai |
|
|
48
|
+
| **engram** (gentle-engram) | Memoria persistente de decisiones | `pi install npm:gentle-engram` | https://www.npmjs.com/package/gentle-engram |
|
|
49
|
+
| **ruflo** | Orquestador multi-agente / swarms (MCP) | `pnpm dlx ruflo@latest init wizard` | https://www.npmjs.com/package/ruflo |
|
|
50
|
+
| **ecc** (ecc-universal) | Auditoría de seguridad, políticas, CVEs | `pnpm add -D ecc-universal` | https://www.npmjs.com/package/ecc-universal |
|
|
51
|
+
| **awesome-copilot** | Catálogo de skills comunitarias (solo lectura) | `git clone … vendor/awesome-copilot` | https://github.com/github/awesome-copilot |
|
|
52
|
+
| **context7** | Documentación técnica al día (MCP) | bajo demanda vía `.mcp.json` | https://github.com/upstash/context7 · https://www.npmjs.com/package/@upstash/context7-mcp |
|
|
53
|
+
| **deepagents** | Workflows persistentes de largo plazo | adaptador propio (`GRU_DEEPAGENTS_ENTRY`) | adaptador provisto por el usuario — sin repo fijo |
|
|
54
|
+
|
|
55
|
+
> Las direcciones apuntan al repositorio o página oficial del paquete de cada
|
|
56
|
+
> proyecto. Si alguna cambia, manda el origen del proyecto upstream.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Qué instala
|
|
61
|
+
|
|
62
|
+
Perfil recomendado (lo que copia por defecto):
|
|
63
|
+
|
|
64
|
+
- `.claude/CLAUDE.md` — la persona Gru (siempre).
|
|
65
|
+
- `minion-contract.md` — contrato de subagentes (siempre).
|
|
66
|
+
- `cybersec-minion-contract.md`, `SDD.md` — contrato cybersec + protocolo SDD.
|
|
67
|
+
- `.mcp.json` — servidores MCP (ruflo, context7, engram). `engram` se deja en
|
|
68
|
+
modo `lazy` y `ENGRAM_BIN=engram`: no intenta arrancar si engram no está.
|
|
69
|
+
- `.claude/agents/` — solo los minions **Gru-nativos** (raíz + `cybersec/`).
|
|
70
|
+
No incluye los agentes/skills específicos de claude-flow.
|
|
71
|
+
- `.claude/output-styles/` — estilos de salida (caveman, etc.).
|
|
72
|
+
|
|
73
|
+
Nunca copia `settings.local.json` (rutas y permisos de tu máquina).
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Tras instalar
|
|
78
|
+
|
|
79
|
+
1. Abre el proyecto con tu harness (Claude Code: `claude`).
|
|
80
|
+
2. Si usas el MCP de engram, ajusta `ENGRAM_BIN` en `.mcp.json` si tu binario no
|
|
81
|
+
está en el `PATH`.
|
|
82
|
+
3. Instala los providers que vayas a usar (ver tabla de arriba).
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Para mantenedores
|
|
87
|
+
|
|
88
|
+
El directorio `template/` se genera desde el repo (fuente única de verdad) para
|
|
89
|
+
evitar drift:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
node scripts/build-installer-template.mjs # también corre en prepublishOnly
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Repositorio del harness Gru: https://github.com/AdrichDev/gru_orchestrator
|
package/index.mjs
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// create-gru — instala el harness Gru (modo B) en un proyecto.
|
|
3
|
+
// Cero dependencias. Copia desde el ./template empaquetado (NO desde el repo),
|
|
4
|
+
// así `pnpm dlx create-gru` es instantáneo: sin monorepo, sin workspace:*,
|
|
5
|
+
// sin postinstall, sin deps nativas.
|
|
6
|
+
//
|
|
7
|
+
// pnpm dlx create-gru init [destino] [flags]
|
|
8
|
+
// npm create gru [destino] # (create-* convention)
|
|
9
|
+
// node packages/create-gru/index.mjs init [destino]
|
|
10
|
+
//
|
|
11
|
+
// Interactivo por TTY (pregunta grupo por grupo). Sin TTY → perfil recomendado.
|
|
12
|
+
|
|
13
|
+
import { existsSync, mkdirSync, cpSync, readFileSync, writeFileSync, statSync, readdirSync } from "node:fs";
|
|
14
|
+
import { dirname, join, resolve, relative } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import readline from "node:readline/promises";
|
|
17
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
18
|
+
|
|
19
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const TEMPLATE = join(__dirname, "template");
|
|
21
|
+
|
|
22
|
+
// --- args -----------------------------------------------------------------
|
|
23
|
+
const rawArgs = process.argv.slice(2);
|
|
24
|
+
const args = rawArgs[0] === "init" ? rawArgs.slice(1) : rawArgs; // tolera "init"
|
|
25
|
+
const flags = new Set(args.filter((a) => a.startsWith("--") || a === "-y"));
|
|
26
|
+
const positionals = args.filter((a) => !a.startsWith("-"));
|
|
27
|
+
|
|
28
|
+
const MINIMAL = flags.has("--minimal");
|
|
29
|
+
const FORCE = flags.has("--force");
|
|
30
|
+
const YES = flags.has("--yes") || flags.has("-y");
|
|
31
|
+
const DRY = flags.has("--dry-run");
|
|
32
|
+
|
|
33
|
+
if (flags.has("--help") || flags.has("-h")) { printHelp(); process.exit(0); }
|
|
34
|
+
|
|
35
|
+
const TARGET = resolve(positionals[0] ?? process.cwd());
|
|
36
|
+
const INTERACTIVE = process.stdin.isTTY && !YES && !MINIMAL && !DRY;
|
|
37
|
+
|
|
38
|
+
if (!existsSync(TEMPLATE)) {
|
|
39
|
+
console.error("Falta el directorio ./template en el paquete. Ejecuta build:template.");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// --- catálogo de grupos ---------------------------------------------------
|
|
44
|
+
// src = ruta relativa dentro de template/. required no se pregunta.
|
|
45
|
+
const GROUPS = [
|
|
46
|
+
{ id: "core", required: true, label: "Persona Gru + contrato de minions",
|
|
47
|
+
paths: [".claude/CLAUDE.md", "minion-contract.md"] },
|
|
48
|
+
{ id: "contracts", default: true, label: "Contrato cybersec + SDD.md",
|
|
49
|
+
paths: ["cybersec-minion-contract.md", "SDD.md"] },
|
|
50
|
+
{ id: "mcp", default: true, label: "Config MCP (.mcp.json: ruflo, context7, engram)",
|
|
51
|
+
paths: [".mcp.json"] },
|
|
52
|
+
{ id: "agents", default: true, label: "Minions / subagentes Gru (.claude/agents)",
|
|
53
|
+
paths: [".claude/agents"] },
|
|
54
|
+
{ id: "styles", default: true, label: "Output styles (caveman, etc.)",
|
|
55
|
+
paths: [".claude/output-styles"] }
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
// --- main -----------------------------------------------------------------
|
|
59
|
+
main().catch((err) => { console.error(err); process.exitCode = 1; });
|
|
60
|
+
|
|
61
|
+
async function main() {
|
|
62
|
+
console.log(`\nGru harness installer (create-gru, modo B)`);
|
|
63
|
+
console.log(`Template: ${TEMPLATE}`);
|
|
64
|
+
console.log(`Destino : ${TARGET}`);
|
|
65
|
+
console.log(`Modo : ${INTERACTIVE ? "interactivo" : MINIMAL ? "minimal" : DRY ? "dry-run" : "recomendado"}\n`);
|
|
66
|
+
|
|
67
|
+
if (resolve(TEMPLATE) === TARGET) {
|
|
68
|
+
console.error("Destino = template. Aborto.");
|
|
69
|
+
process.exit(2);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const enabled = await resolveSelection();
|
|
73
|
+
|
|
74
|
+
let copied = 0, skipped = 0;
|
|
75
|
+
for (const group of GROUPS) {
|
|
76
|
+
if (!group.required && !enabled.has(group.id)) continue;
|
|
77
|
+
for (const p of group.paths) {
|
|
78
|
+
const r = copyPath(p);
|
|
79
|
+
copied += r.copied;
|
|
80
|
+
skipped += r.skipped;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
console.log(`\nListo. ${copied} archivos copiados, ${skipped} omitidos.`);
|
|
85
|
+
if (!DRY) printNextSteps();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// --- selección ------------------------------------------------------------
|
|
89
|
+
async function resolveSelection() {
|
|
90
|
+
const optional = GROUPS.filter((g) => !g.required);
|
|
91
|
+
if (MINIMAL) return new Set();
|
|
92
|
+
if (!INTERACTIVE) return new Set(optional.filter((g) => g.default).map((g) => g.id));
|
|
93
|
+
|
|
94
|
+
console.log("Elige qué instalar (Enter = valor por defecto):\n");
|
|
95
|
+
const enabled = new Set();
|
|
96
|
+
const rl = readline.createInterface({ input, output });
|
|
97
|
+
const ac = new AbortController();
|
|
98
|
+
const onEnd = () => ac.abort();
|
|
99
|
+
input.once("end", onEnd);
|
|
100
|
+
input.once("close", onEnd);
|
|
101
|
+
try {
|
|
102
|
+
for (let i = 0; i < optional.length; i++) {
|
|
103
|
+
const g = optional[i];
|
|
104
|
+
let ans;
|
|
105
|
+
try {
|
|
106
|
+
ans = (await rl.question(` ${g.label}? ${g.default ? "(S/n)" : "(s/N)"} `, { signal: ac.signal }))
|
|
107
|
+
.trim().toLowerCase();
|
|
108
|
+
} catch {
|
|
109
|
+
// stdin cerrado a mitad: el resto toma su valor por defecto.
|
|
110
|
+
for (const rest of optional.slice(i)) if (rest.default) enabled.add(rest.id);
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
const yes = ans === "" ? g.default : /^s|^y/.test(ans);
|
|
114
|
+
if (yes) enabled.add(g.id);
|
|
115
|
+
}
|
|
116
|
+
} finally {
|
|
117
|
+
input.off("end", onEnd);
|
|
118
|
+
input.off("close", onEnd);
|
|
119
|
+
rl.close();
|
|
120
|
+
}
|
|
121
|
+
return enabled;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// --- copia por archivo (merge, nunca skip de directorio entero) ------------
|
|
125
|
+
function copyPath(relPath) {
|
|
126
|
+
const src = join(TEMPLATE, relPath);
|
|
127
|
+
if (!existsSync(src)) {
|
|
128
|
+
console.warn(` SKIP ${relPath} (no está en el template)`);
|
|
129
|
+
return { copied: 0, skipped: 1 };
|
|
130
|
+
}
|
|
131
|
+
return statSync(src).isDirectory() ? copyDir(relPath) : copyFile(relPath);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function copyDir(relPath) {
|
|
135
|
+
let copied = 0, skipped = 0;
|
|
136
|
+
const src = join(TEMPLATE, relPath);
|
|
137
|
+
for (const entry of readdirSync(src, { withFileTypes: true })) {
|
|
138
|
+
const child = `${relPath}/${entry.name}`;
|
|
139
|
+
const r = entry.isDirectory() ? copyDir(child) : copyFile(child);
|
|
140
|
+
copied += r.copied; skipped += r.skipped;
|
|
141
|
+
}
|
|
142
|
+
return { copied, skipped };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function copyFile(relPath) {
|
|
146
|
+
const src = join(TEMPLATE, relPath);
|
|
147
|
+
const dst = join(TARGET, relPath);
|
|
148
|
+
const exists = existsSync(dst);
|
|
149
|
+
|
|
150
|
+
if (exists && !FORCE) {
|
|
151
|
+
console.log(` SKIP ${relPath} (ya existe — usa --force)`);
|
|
152
|
+
return { copied: 0, skipped: 1 };
|
|
153
|
+
}
|
|
154
|
+
if (DRY) {
|
|
155
|
+
console.log(` COPY ${relPath}${exists ? " (overwrite)" : ""}`);
|
|
156
|
+
return { copied: 1, skipped: 0 };
|
|
157
|
+
}
|
|
158
|
+
mkdirSync(dirname(dst), { recursive: true });
|
|
159
|
+
cpSync(src, dst);
|
|
160
|
+
console.log(` ${exists ? "OVERWRITE" : "COPY"} ${relPath}`);
|
|
161
|
+
return { copied: 1, skipped: 0 };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// --- final ----------------------------------------------------------------
|
|
165
|
+
function printNextSteps() {
|
|
166
|
+
const rel = relative(process.cwd(), TARGET) || ".";
|
|
167
|
+
console.log(`
|
|
168
|
+
Siguientes pasos:
|
|
169
|
+
1. Abre el proyecto con tu harness (Claude Code: 'claude' en ${rel}).
|
|
170
|
+
2. Si usas el MCP de engram, ajústalo en ${join(rel, ".mcp.json")}
|
|
171
|
+
(ENGRAM_BIN debe apuntar a tu binario si no está en PATH).
|
|
172
|
+
3. Instala los providers que vayas a usar, p.ej.:
|
|
173
|
+
npm install -g pi && pi install npm:gentle-engram # engram
|
|
174
|
+
pnpm dlx ruflo@latest init wizard # ruflo (swarm)
|
|
175
|
+
pnpm add -D ecc-universal # ecc (seguridad)
|
|
176
|
+
|
|
177
|
+
Nota: este instalador trae solo los minions Gru-nativos; no incluye los
|
|
178
|
+
agents/skills específicos de claude-flow.`);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function printHelp() {
|
|
182
|
+
console.log(`
|
|
183
|
+
create-gru — instala el harness Gru (modo B) en un proyecto. Cero dependencias.
|
|
184
|
+
|
|
185
|
+
Uso:
|
|
186
|
+
pnpm dlx create-gru init [destino] [flags]
|
|
187
|
+
node packages/create-gru/index.mjs init [destino] [flags]
|
|
188
|
+
|
|
189
|
+
Interactivo con TTY (pregunta qué piezas instalar). Sin TTY → recomendado.
|
|
190
|
+
Siempre copia CLAUDE.md + minion-contract.md.
|
|
191
|
+
|
|
192
|
+
Flags:
|
|
193
|
+
--yes, -y No preguntar: perfil recomendado.
|
|
194
|
+
--minimal Solo CLAUDE.md + minion-contract.md.
|
|
195
|
+
--force Sobrescribe archivos existentes (copia por archivo, hace merge).
|
|
196
|
+
--dry-run Muestra qué haría, sin escribir.
|
|
197
|
+
-h, --help Esta ayuda.`);
|
|
198
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-gru",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Instalador del harness Gru (modo B) en cualquier proyecto. Cero dependencias. Para uso propio, no comercial.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "ISC",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"gru",
|
|
9
|
+
"harness",
|
|
10
|
+
"orchestrator",
|
|
11
|
+
"claude-code",
|
|
12
|
+
"scaffold",
|
|
13
|
+
"init"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/AdrichDev/gru_orchestrator/tree/main/packages/create-gru#readme",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/AdrichDev/gru_orchestrator.git",
|
|
19
|
+
"directory": "packages/create-gru"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/AdrichDev/gru_orchestrator/issues"
|
|
23
|
+
},
|
|
24
|
+
"bin": {
|
|
25
|
+
"create-gru": "index.mjs",
|
|
26
|
+
"gru-init": "index.mjs"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"index.mjs",
|
|
30
|
+
"template",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build:template": "node ../../scripts/build-installer-template.mjs",
|
|
35
|
+
"prepublishOnly": "node ../../scripts/build-installer-template.mjs"
|
|
36
|
+
}
|
|
37
|
+
}
|