maestro-bundle 1.1.0 → 1.2.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/package.json +1 -1
- package/src/cli.mjs +100 -46
package/package.json
CHANGED
package/src/cli.mjs
CHANGED
|
@@ -69,9 +69,9 @@ const EDITORS = {
|
|
|
69
69
|
},
|
|
70
70
|
cursor: {
|
|
71
71
|
name: "Cursor",
|
|
72
|
-
instructionsFile: null, // Cursor lê AGENTS.md
|
|
73
|
-
skillsDir:
|
|
74
|
-
rulesDir:
|
|
72
|
+
instructionsFile: null, // Cursor lê AGENTS.md na raiz
|
|
73
|
+
skillsDir: ".cursor/skills", // Skills como SKILL.md (mesmo formato do Claude)
|
|
74
|
+
rulesDir: null, // Não usar rules, usar skills
|
|
75
75
|
needsAgentsMd: true, // Cursor lê AGENTS.md na raiz
|
|
76
76
|
},
|
|
77
77
|
codex: {
|
|
@@ -116,8 +116,8 @@ function showHelp() {
|
|
|
116
116
|
}
|
|
117
117
|
console.log("");
|
|
118
118
|
console.log(chalk.dim(" Editores:"));
|
|
119
|
-
console.log(` ${chalk.yellow("claude".padEnd(12))} CLAUDE.md + .claude/skills
|
|
120
|
-
console.log(` ${chalk.yellow("cursor".padEnd(12))} AGENTS.md + .cursor/
|
|
119
|
+
console.log(` ${chalk.yellow("claude".padEnd(12))} CLAUDE.md + .claude/skills/<nome>/SKILL.md`);
|
|
120
|
+
console.log(` ${chalk.yellow("cursor".padEnd(12))} AGENTS.md + .cursor/skills/<nome>/SKILL.md`);
|
|
121
121
|
console.log(` ${chalk.yellow("codex".padEnd(12))} AGENTS.md (tudo em um arquivo)`);
|
|
122
122
|
console.log(` ${chalk.yellow("copilot".padEnd(12))} .github/copilot-instructions.md + .github/instructions/`);
|
|
123
123
|
console.log(` ${chalk.yellow("windsurf".padEnd(12))} .windsurfrules (tudo em um arquivo)`);
|
|
@@ -205,21 +205,7 @@ function installForEditor(editorKey, agentsMd, skills, targetDir) {
|
|
|
205
205
|
for (const skill of skills) {
|
|
206
206
|
const content = readFileSync(join(skill.dir, "SKILL.md"), "utf-8");
|
|
207
207
|
|
|
208
|
-
if (editorKey === "
|
|
209
|
-
// Cursor: .mdc com frontmatter (description + globs)
|
|
210
|
-
// Extrair frontmatter existente e converter
|
|
211
|
-
const parsed = parseFrontmatter(content);
|
|
212
|
-
const cursorContent = [
|
|
213
|
-
"---",
|
|
214
|
-
`description: "${parsed.description || skill.name}"`,
|
|
215
|
-
`alwaysApply: false`,
|
|
216
|
-
"---",
|
|
217
|
-
"",
|
|
218
|
-
parsed.body,
|
|
219
|
-
].join("\n");
|
|
220
|
-
writeFileSync(join(rulesPath, `${skill.name}.mdc`), cursorContent);
|
|
221
|
-
|
|
222
|
-
} else if (editorKey === "copilot") {
|
|
208
|
+
if (editorKey === "copilot") {
|
|
223
209
|
// Copilot: .instructions.md
|
|
224
210
|
writeFileSync(join(rulesPath, `${skill.name}.instructions.md`), content);
|
|
225
211
|
|
|
@@ -324,38 +310,101 @@ async function main() {
|
|
|
324
310
|
}
|
|
325
311
|
spinner2.succeed(`${skills.length} skills canônicas em skills/`);
|
|
326
312
|
|
|
327
|
-
// 3.
|
|
328
|
-
const spinner3 = ora("Instalando
|
|
329
|
-
const specSrc = join(bundleDir, ".spec");
|
|
330
|
-
ensureDir(join(targetDir, ".spec"));
|
|
331
|
-
copyDir(specSrc, join(targetDir, ".spec"));
|
|
332
|
-
spinner3.succeed(".spec/constitution.md instalado");
|
|
333
|
-
|
|
334
|
-
// 4. References
|
|
335
|
-
const spinner4 = ora("Instalando references").start();
|
|
313
|
+
// 3. References
|
|
314
|
+
const spinner3 = ora("Instalando references").start();
|
|
336
315
|
const refsSrc = join(bundleDir, "references");
|
|
337
316
|
ensureDir(join(targetDir, "references"));
|
|
338
317
|
if (existsSync(refsSrc)) {
|
|
339
318
|
copyDir(refsSrc, join(targetDir, "references"));
|
|
340
319
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
//
|
|
344
|
-
|
|
320
|
+
spinner3.succeed("references/ pronto");
|
|
321
|
+
|
|
322
|
+
// 4. GitHub Spec Kit — instalar CLI + inicializar no projeto
|
|
323
|
+
// Mapear editor para flag --ai do specify
|
|
324
|
+
const aiFlags = {
|
|
325
|
+
claude: "claude",
|
|
326
|
+
cursor: "cursor",
|
|
327
|
+
codex: "codex",
|
|
328
|
+
copilot: "copilot",
|
|
329
|
+
windsurf: "windsurf",
|
|
330
|
+
};
|
|
331
|
+
// Usar o primeiro editor como --ai (ou claude como default)
|
|
332
|
+
const primaryEditor = editorsToInstall[0];
|
|
333
|
+
const aiFlag = aiFlags[primaryEditor] || "claude";
|
|
334
|
+
|
|
335
|
+
// 4a. Instalar specify-cli se não tiver
|
|
336
|
+
const spinner4 = ora("Verificando GitHub Spec Kit (specify-cli)").start();
|
|
337
|
+
let specifyInstalled = false;
|
|
345
338
|
try {
|
|
346
339
|
execSync("specify --version", { stdio: "ignore" });
|
|
347
|
-
|
|
340
|
+
specifyInstalled = true;
|
|
341
|
+
spinner4.succeed("specify-cli já instalado");
|
|
348
342
|
} catch {
|
|
349
|
-
|
|
350
|
-
const
|
|
343
|
+
spinner4.info("specify-cli não encontrado");
|
|
344
|
+
const spinner4b = ora("Instalando specify-cli...").start();
|
|
351
345
|
try {
|
|
352
|
-
|
|
346
|
+
const SPECKIT_VERSION = "v0.4.3";
|
|
347
|
+
execSync(`uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@${SPECKIT_VERSION}`, {
|
|
353
348
|
stdio: "ignore", timeout: 120000,
|
|
354
349
|
});
|
|
355
|
-
|
|
350
|
+
specifyInstalled = true;
|
|
351
|
+
spinner4b.succeed(`specify-cli ${SPECKIT_VERSION} instalado`);
|
|
356
352
|
} catch {
|
|
357
|
-
|
|
358
|
-
|
|
353
|
+
try {
|
|
354
|
+
const SPECKIT_VERSION = "v0.4.3";
|
|
355
|
+
execSync(`pip install specify-cli --src git+https://github.com/github/spec-kit.git@${SPECKIT_VERSION}`, {
|
|
356
|
+
stdio: "ignore", timeout: 60000,
|
|
357
|
+
});
|
|
358
|
+
specifyInstalled = true;
|
|
359
|
+
spinner4b.succeed("specify-cli instalado via pip");
|
|
360
|
+
} catch {
|
|
361
|
+
spinner4b.warn("Não foi possível instalar. Instale manualmente:");
|
|
362
|
+
console.log(chalk.dim(" uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@v0.4.3"));
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// 4b. Rodar specify init no projeto para criar .specify/ e registrar /speckit.* commands
|
|
368
|
+
if (specifyInstalled) {
|
|
369
|
+
const spinner4c = ora(`Inicializando Spec Kit no projeto (--ai ${aiFlag})`).start();
|
|
370
|
+
const specifyEnv = { ...process.env, PYTHONIOENCODING: "utf-8", PYTHONUTF8: "1" };
|
|
371
|
+
let specInitOk = false;
|
|
372
|
+
const initCmds = [
|
|
373
|
+
`specify init --here --ai ${aiFlag}`,
|
|
374
|
+
`specify init . --ai ${aiFlag}`,
|
|
375
|
+
`specify init --here --ai ${aiFlag} --no-git`,
|
|
376
|
+
];
|
|
377
|
+
for (const cmd of initCmds) {
|
|
378
|
+
try {
|
|
379
|
+
execSync(cmd, { stdio: "ignore", timeout: 30000, cwd: targetDir, env: specifyEnv });
|
|
380
|
+
specInitOk = true;
|
|
381
|
+
break;
|
|
382
|
+
} catch { /* try next */ }
|
|
383
|
+
}
|
|
384
|
+
if (specInitOk) {
|
|
385
|
+
spinner4c.succeed(`Spec Kit inicializado (/speckit.* commands disponíveis)`);
|
|
386
|
+
} else {
|
|
387
|
+
spinner4c.warn("Inicialize manualmente no terminal:");
|
|
388
|
+
console.log(chalk.dim(` cd ${targetDir}`));
|
|
389
|
+
console.log(chalk.dim(` specify init --here --ai ${aiFlag}`));
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// 4c. Copiar constitution.md do bundle para dentro do .specify/memory/
|
|
393
|
+
const specifyMemoryDir = join(targetDir, ".specify", "memory");
|
|
394
|
+
const bundleConstitution = join(bundleDir, ".spec", "constitution.md");
|
|
395
|
+
if (existsSync(bundleConstitution)) {
|
|
396
|
+
ensureDir(specifyMemoryDir);
|
|
397
|
+
const constitutionDest = join(specifyMemoryDir, "constitution.md");
|
|
398
|
+
// Append os princípios do bundle ao constitution gerado pelo specify
|
|
399
|
+
if (existsSync(constitutionDest)) {
|
|
400
|
+
const existing = readFileSync(constitutionDest, "utf-8");
|
|
401
|
+
const bundleContent = readFileSync(bundleConstitution, "utf-8");
|
|
402
|
+
writeFileSync(constitutionDest, existing + "\n\n---\n\n" + bundleContent);
|
|
403
|
+
} else {
|
|
404
|
+
cpSync(bundleConstitution, constitutionDest);
|
|
405
|
+
}
|
|
406
|
+
const spinner4d = ora("Constitution do bundle integrado ao Spec Kit").start();
|
|
407
|
+
spinner4d.succeed("Constitution do bundle integrado ao Spec Kit");
|
|
359
408
|
}
|
|
360
409
|
}
|
|
361
410
|
|
|
@@ -373,7 +422,7 @@ async function main() {
|
|
|
373
422
|
console.log(` ${chalk.cyan(".claude/skills/")} (${skills.length} skills com SKILL.md)`);
|
|
374
423
|
} else if (editorKey === "cursor") {
|
|
375
424
|
console.log(` ${chalk.cyan("AGENTS.md")} (instruções gerais)`);
|
|
376
|
-
console.log(` ${chalk.cyan(".cursor/
|
|
425
|
+
console.log(` ${chalk.cyan(".cursor/skills/")} (${skills.length} skills com SKILL.md)`);
|
|
377
426
|
} else if (editorKey === "codex") {
|
|
378
427
|
console.log(` ${chalk.cyan("AGENTS.md")} (tudo em um arquivo)`);
|
|
379
428
|
} else if (editorKey === "copilot") {
|
|
@@ -384,12 +433,17 @@ async function main() {
|
|
|
384
433
|
}
|
|
385
434
|
}
|
|
386
435
|
console.log(` ${chalk.cyan("skills/")} (${skills.length} canônicas para Deep Agents)`);
|
|
387
|
-
console.log(` ${chalk.cyan(".
|
|
436
|
+
console.log(` ${chalk.cyan(".specify/")} (GitHub Spec Kit — /speckit.* commands)`);
|
|
437
|
+
console.log("");
|
|
438
|
+
console.log(" Comandos SDD disponíveis no editor:");
|
|
439
|
+
console.log(` ${chalk.cyan("/speckit.constitution")} — Definir princípios do projeto`);
|
|
440
|
+
console.log(` ${chalk.cyan("/speckit.specify")} — Especificar O QUE e POR QUÊ`);
|
|
441
|
+
console.log(` ${chalk.cyan("/speckit.plan")} — Planejar arquitetura e stack`);
|
|
442
|
+
console.log(` ${chalk.cyan("/speckit.tasks")} — Quebrar em tasks atômicas`);
|
|
443
|
+
console.log(` ${chalk.cyan("/speckit.implement")} — Executar as tasks`);
|
|
388
444
|
console.log("");
|
|
389
|
-
console.log("
|
|
390
|
-
console.log("
|
|
391
|
-
console.log(" 2. O agente já conhece os padrões");
|
|
392
|
-
console.log(` 3. Nova demanda? ${chalk.cyan("/speckit.specify")}`);
|
|
445
|
+
console.log(" Próximo passo:");
|
|
446
|
+
console.log(" Abra o projeto no editor AI e use " + chalk.cyan("/speckit.specify") + " para começar");
|
|
393
447
|
console.log("");
|
|
394
448
|
}
|
|
395
449
|
|