@nimbuslab/cli 0.11.0 → 0.13.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/dist/index.js +398 -101
- package/package.json +1 -1
- package/src/commands/lola.ts +171 -0
- package/src/commands/update.ts +152 -0
- package/src/index.ts +36 -27
package/dist/index.js
CHANGED
|
@@ -150,7 +150,7 @@ var require_src = __commonJS((exports, module) => {
|
|
|
150
150
|
var require_package = __commonJS((exports, module) => {
|
|
151
151
|
module.exports = {
|
|
152
152
|
name: "@nimbuslab/cli",
|
|
153
|
-
version: "0.
|
|
153
|
+
version: "0.13.0",
|
|
154
154
|
description: "CLI para criar projetos nimbuslab",
|
|
155
155
|
type: "module",
|
|
156
156
|
bin: {
|
|
@@ -192,7 +192,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
192
192
|
});
|
|
193
193
|
|
|
194
194
|
// src/index.ts
|
|
195
|
-
var
|
|
195
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
196
196
|
|
|
197
197
|
// node_modules/@clack/core/dist/index.mjs
|
|
198
198
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
@@ -833,6 +833,29 @@ ${import_picocolors2.default.gray(d2)} ${t}
|
|
|
833
833
|
|
|
834
834
|
`);
|
|
835
835
|
};
|
|
836
|
+
var M2 = { message: (t = "", { symbol: n = import_picocolors2.default.gray(o) } = {}) => {
|
|
837
|
+
const r2 = [`${import_picocolors2.default.gray(o)}`];
|
|
838
|
+
if (t) {
|
|
839
|
+
const [i, ...s] = t.split(`
|
|
840
|
+
`);
|
|
841
|
+
r2.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors2.default.gray(o)} ${c}`));
|
|
842
|
+
}
|
|
843
|
+
process.stdout.write(`${r2.join(`
|
|
844
|
+
`)}
|
|
845
|
+
`);
|
|
846
|
+
}, info: (t) => {
|
|
847
|
+
M2.message(t, { symbol: import_picocolors2.default.blue(q) });
|
|
848
|
+
}, success: (t) => {
|
|
849
|
+
M2.message(t, { symbol: import_picocolors2.default.green(D) });
|
|
850
|
+
}, step: (t) => {
|
|
851
|
+
M2.message(t, { symbol: import_picocolors2.default.green(C) });
|
|
852
|
+
}, warn: (t) => {
|
|
853
|
+
M2.message(t, { symbol: import_picocolors2.default.yellow(U) });
|
|
854
|
+
}, warning: (t) => {
|
|
855
|
+
M2.warn(t);
|
|
856
|
+
}, error: (t) => {
|
|
857
|
+
M2.message(t, { symbol: import_picocolors2.default.red(K2) });
|
|
858
|
+
} };
|
|
836
859
|
var J2 = `${import_picocolors2.default.gray(o)} `;
|
|
837
860
|
var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
838
861
|
const n = V2 ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], r2 = V2 ? 80 : 120, i = process.env.CI === "true";
|
|
@@ -2328,8 +2351,123 @@ function printUpgradePlan(name, plan) {
|
|
|
2328
2351
|
console.log();
|
|
2329
2352
|
}
|
|
2330
2353
|
|
|
2331
|
-
// src/commands/
|
|
2354
|
+
// src/commands/update.ts
|
|
2332
2355
|
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
2356
|
+
import { execSync, spawnSync } from "child_process";
|
|
2357
|
+
var PACKAGE_NAME = "@nimbuslab/cli";
|
|
2358
|
+
async function getAvailableVersions() {
|
|
2359
|
+
try {
|
|
2360
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`);
|
|
2361
|
+
if (!res.ok)
|
|
2362
|
+
return [];
|
|
2363
|
+
const data = await res.json();
|
|
2364
|
+
return Object.keys(data.versions || {}).reverse();
|
|
2365
|
+
} catch {
|
|
2366
|
+
return [];
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
async function getLatestVersion() {
|
|
2370
|
+
try {
|
|
2371
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`);
|
|
2372
|
+
if (!res.ok)
|
|
2373
|
+
return null;
|
|
2374
|
+
const data = await res.json();
|
|
2375
|
+
return data.version || null;
|
|
2376
|
+
} catch {
|
|
2377
|
+
return null;
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
function getCurrentVersion() {
|
|
2381
|
+
try {
|
|
2382
|
+
const result = spawnSync("npm", ["ls", "-g", PACKAGE_NAME, "--json"], {
|
|
2383
|
+
encoding: "utf-8",
|
|
2384
|
+
shell: true
|
|
2385
|
+
});
|
|
2386
|
+
if (result.stdout) {
|
|
2387
|
+
const data = JSON.parse(result.stdout);
|
|
2388
|
+
return data.dependencies?.[PACKAGE_NAME]?.version || "unknown";
|
|
2389
|
+
}
|
|
2390
|
+
} catch {}
|
|
2391
|
+
return "unknown";
|
|
2392
|
+
}
|
|
2393
|
+
async function update(args) {
|
|
2394
|
+
const flag = args[0];
|
|
2395
|
+
if (flag === "--list" || flag === "-l") {
|
|
2396
|
+
Ie(import_picocolors6.default.cyan("Vers\xF5es dispon\xEDveis"));
|
|
2397
|
+
const spinner2 = Y2();
|
|
2398
|
+
spinner2.start("Buscando vers\xF5es...");
|
|
2399
|
+
const versions = await getAvailableVersions();
|
|
2400
|
+
spinner2.stop("Vers\xF5es encontradas");
|
|
2401
|
+
if (versions.length === 0) {
|
|
2402
|
+
M2.error("N\xE3o foi poss\xEDvel buscar as vers\xF5es");
|
|
2403
|
+
return;
|
|
2404
|
+
}
|
|
2405
|
+
const current = getCurrentVersion();
|
|
2406
|
+
console.log();
|
|
2407
|
+
console.log(import_picocolors6.default.bold("\xDAltimas 10 vers\xF5es:"));
|
|
2408
|
+
versions.slice(0, 10).forEach((v2, i) => {
|
|
2409
|
+
const isCurrent = v2 === current;
|
|
2410
|
+
const prefix = isCurrent ? import_picocolors6.default.green("\u2192 ") : " ";
|
|
2411
|
+
const suffix = isCurrent ? import_picocolors6.default.dim(" (instalada)") : "";
|
|
2412
|
+
const isLatest = i === 0 ? import_picocolors6.default.yellow(" (latest)") : "";
|
|
2413
|
+
console.log(`${prefix}${v2}${suffix}${isLatest}`);
|
|
2414
|
+
});
|
|
2415
|
+
console.log();
|
|
2416
|
+
console.log(import_picocolors6.default.dim(`Total: ${versions.length} vers\xF5es`));
|
|
2417
|
+
console.log(import_picocolors6.default.dim(`Instalar vers\xE3o espec\xEDfica: nimbus update <vers\xE3o>`));
|
|
2418
|
+
return;
|
|
2419
|
+
}
|
|
2420
|
+
const targetVersion = flag || "latest";
|
|
2421
|
+
const isSpecificVersion = flag && flag !== "latest";
|
|
2422
|
+
Ie(import_picocolors6.default.cyan(`Atualizando ${PACKAGE_NAME}`));
|
|
2423
|
+
const spinner = Y2();
|
|
2424
|
+
spinner.start("Verificando vers\xE3o atual...");
|
|
2425
|
+
const currentVersion = getCurrentVersion();
|
|
2426
|
+
spinner.stop(`Vers\xE3o atual: ${currentVersion}`);
|
|
2427
|
+
if (!isSpecificVersion) {
|
|
2428
|
+
spinner.start("Verificando \xFAltima vers\xE3o...");
|
|
2429
|
+
const latest = await getLatestVersion();
|
|
2430
|
+
spinner.stop(`\xDAltima vers\xE3o: ${latest || "desconhecida"}`);
|
|
2431
|
+
if (latest && latest === currentVersion) {
|
|
2432
|
+
M2.success("Voc\xEA j\xE1 est\xE1 na \xFAltima vers\xE3o!");
|
|
2433
|
+
return;
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
const versionText = isSpecificVersion ? targetVersion : "latest";
|
|
2437
|
+
const confirmUpdate = await ye({
|
|
2438
|
+
message: `Atualizar para ${versionText}?`,
|
|
2439
|
+
initialValue: true
|
|
2440
|
+
});
|
|
2441
|
+
if (pD(confirmUpdate) || !confirmUpdate) {
|
|
2442
|
+
xe("Atualiza\xE7\xE3o cancelada");
|
|
2443
|
+
return;
|
|
2444
|
+
}
|
|
2445
|
+
spinner.start("Atualizando...");
|
|
2446
|
+
try {
|
|
2447
|
+
const packageSpec = isSpecificVersion ? `${PACKAGE_NAME}@${targetVersion}` : PACKAGE_NAME;
|
|
2448
|
+
execSync(`npm install -g ${packageSpec}`, {
|
|
2449
|
+
stdio: "pipe",
|
|
2450
|
+
encoding: "utf-8"
|
|
2451
|
+
});
|
|
2452
|
+
spinner.stop("Atualiza\xE7\xE3o conclu\xEDda!");
|
|
2453
|
+
const newVersion = getCurrentVersion();
|
|
2454
|
+
M2.success(`${PACKAGE_NAME} atualizado: ${currentVersion} \u2192 ${newVersion}`);
|
|
2455
|
+
Se(import_picocolors6.default.green("Pronto!"));
|
|
2456
|
+
} catch (error) {
|
|
2457
|
+
spinner.stop("Erro na atualiza\xE7\xE3o");
|
|
2458
|
+
const err = error;
|
|
2459
|
+
M2.error("Falha ao atualizar");
|
|
2460
|
+
if (err.stderr) {
|
|
2461
|
+
console.log(import_picocolors6.default.dim(err.stderr));
|
|
2462
|
+
}
|
|
2463
|
+
console.log();
|
|
2464
|
+
console.log(import_picocolors6.default.yellow("Tente manualmente:"));
|
|
2465
|
+
console.log(import_picocolors6.default.cyan(` npm install -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
// src/commands/lola.ts
|
|
2470
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
2333
2471
|
import { existsSync as existsSync2 } from "fs";
|
|
2334
2472
|
import { join as join3 } from "path";
|
|
2335
2473
|
var LOLA_DIR = join3(process.env.HOME || "~", ".lola");
|
|
@@ -2337,40 +2475,40 @@ var LOLA_REPO = "git@github.com:nimbuslab/lola.git";
|
|
|
2337
2475
|
var USER_MEMORY = join3(process.env.HOME || "~", ".claude", "USER_MEMORY.md");
|
|
2338
2476
|
async function installLola() {
|
|
2339
2477
|
console.log();
|
|
2340
|
-
console.log(
|
|
2341
|
-
console.log(
|
|
2478
|
+
console.log(import_picocolors7.default.cyan(" Lola - Code Agent da nimbuslab"));
|
|
2479
|
+
console.log(import_picocolors7.default.dim(" ==============================="));
|
|
2342
2480
|
console.log();
|
|
2343
2481
|
const isUpdate = existsSync2(LOLA_DIR);
|
|
2344
2482
|
if (isUpdate) {
|
|
2345
|
-
console.log(
|
|
2346
|
-
console.log(
|
|
2483
|
+
console.log(import_picocolors7.default.dim(` Lola ja instalada em ${LOLA_DIR}`));
|
|
2484
|
+
console.log(import_picocolors7.default.cyan(" Atualizando..."));
|
|
2347
2485
|
const result = Bun.spawnSync(["git", "pull", "--quiet"], {
|
|
2348
2486
|
cwd: LOLA_DIR,
|
|
2349
2487
|
stdout: "inherit",
|
|
2350
2488
|
stderr: "inherit"
|
|
2351
2489
|
});
|
|
2352
2490
|
if (result.exitCode !== 0) {
|
|
2353
|
-
console.log(
|
|
2491
|
+
console.log(import_picocolors7.default.red(" Erro ao atualizar Lola"));
|
|
2354
2492
|
process.exit(1);
|
|
2355
2493
|
}
|
|
2356
|
-
console.log(
|
|
2494
|
+
console.log(import_picocolors7.default.green(" Atualizado!"));
|
|
2357
2495
|
} else {
|
|
2358
|
-
console.log(
|
|
2496
|
+
console.log(import_picocolors7.default.cyan(` Instalando Lola em ${LOLA_DIR}...`));
|
|
2359
2497
|
const result = Bun.spawnSync(["git", "clone", "--quiet", LOLA_REPO, LOLA_DIR], {
|
|
2360
2498
|
stdout: "inherit",
|
|
2361
2499
|
stderr: "inherit"
|
|
2362
2500
|
});
|
|
2363
2501
|
if (result.exitCode !== 0) {
|
|
2364
|
-
console.log(
|
|
2365
|
-
console.log(
|
|
2502
|
+
console.log(import_picocolors7.default.red(" Erro ao clonar repositorio"));
|
|
2503
|
+
console.log(import_picocolors7.default.dim(" Verifique se tem acesso ao repo nimbuslab/lola"));
|
|
2366
2504
|
process.exit(1);
|
|
2367
2505
|
}
|
|
2368
|
-
console.log(
|
|
2506
|
+
console.log(import_picocolors7.default.green(" Instalado!"));
|
|
2369
2507
|
}
|
|
2370
2508
|
const claudeDir = join3(process.env.HOME || "~", ".claude");
|
|
2371
2509
|
if (!existsSync2(USER_MEMORY)) {
|
|
2372
2510
|
console.log();
|
|
2373
|
-
console.log(
|
|
2511
|
+
console.log(import_picocolors7.default.cyan(" Criando USER_MEMORY.md..."));
|
|
2374
2512
|
await Bun.$`mkdir -p ${claudeDir}`;
|
|
2375
2513
|
const content = `# User Memory
|
|
2376
2514
|
|
|
@@ -2393,29 +2531,29 @@ lola_profile: millennial
|
|
|
2393
2531
|
---
|
|
2394
2532
|
`;
|
|
2395
2533
|
await Bun.write(USER_MEMORY, content);
|
|
2396
|
-
console.log(
|
|
2534
|
+
console.log(import_picocolors7.default.green(" USER_MEMORY.md criado!"));
|
|
2397
2535
|
}
|
|
2398
2536
|
console.log();
|
|
2399
|
-
console.log(
|
|
2537
|
+
console.log(import_picocolors7.default.green(" Instalacao concluida!"));
|
|
2400
2538
|
console.log();
|
|
2401
|
-
console.log(
|
|
2402
|
-
console.log(
|
|
2403
|
-
console.log(
|
|
2539
|
+
console.log(import_picocolors7.default.bold(" Para usar a Lola:"));
|
|
2540
|
+
console.log(import_picocolors7.default.dim(" lola ") + import_picocolors7.default.white("# Iniciar sessao"));
|
|
2541
|
+
console.log(import_picocolors7.default.dim(' lola suggest "x" ') + import_picocolors7.default.white("# Sugerir melhoria"));
|
|
2404
2542
|
console.log();
|
|
2405
|
-
console.log(
|
|
2406
|
-
console.log(
|
|
2543
|
+
console.log(import_picocolors7.default.bold(" Para mudar perfil, edite ~/.claude/USER_MEMORY.md:"));
|
|
2544
|
+
console.log(import_picocolors7.default.dim(" lola_profile: millennial|genz|profissional|nerd|chill"));
|
|
2407
2545
|
console.log();
|
|
2408
2546
|
}
|
|
2409
2547
|
async function suggestImprovement(message) {
|
|
2410
2548
|
if (!message) {
|
|
2411
|
-
console.log(
|
|
2412
|
-
console.log(
|
|
2549
|
+
console.log(import_picocolors7.default.red(" Erro: forne\xE7a uma mensagem"));
|
|
2550
|
+
console.log(import_picocolors7.default.dim(' Uso: nimbus lola suggest "sua sugestao aqui"'));
|
|
2413
2551
|
process.exit(1);
|
|
2414
2552
|
}
|
|
2415
2553
|
const ghCheck = Bun.spawnSync(["which", "gh"]);
|
|
2416
2554
|
if (ghCheck.exitCode !== 0) {
|
|
2417
|
-
console.log(
|
|
2418
|
-
console.log(
|
|
2555
|
+
console.log(import_picocolors7.default.red(" Erro: GitHub CLI (gh) nao encontrado"));
|
|
2556
|
+
console.log(import_picocolors7.default.dim(" Instale: https://cli.github.com"));
|
|
2419
2557
|
process.exit(1);
|
|
2420
2558
|
}
|
|
2421
2559
|
const authCheck = Bun.spawnSync(["gh", "auth", "status"], {
|
|
@@ -2423,8 +2561,8 @@ async function suggestImprovement(message) {
|
|
|
2423
2561
|
stderr: "pipe"
|
|
2424
2562
|
});
|
|
2425
2563
|
if (authCheck.exitCode !== 0) {
|
|
2426
|
-
console.log(
|
|
2427
|
-
console.log(
|
|
2564
|
+
console.log(import_picocolors7.default.red(" Erro: GitHub CLI nao autenticado"));
|
|
2565
|
+
console.log(import_picocolors7.default.dim(" Execute: gh auth login"));
|
|
2428
2566
|
process.exit(1);
|
|
2429
2567
|
}
|
|
2430
2568
|
const gitUser = Bun.spawnSync(["git", "config", "user.name"], { stdout: "pipe" });
|
|
@@ -2432,7 +2570,7 @@ async function suggestImprovement(message) {
|
|
|
2432
2570
|
const userName = gitUser.stdout.toString().trim() || "Dev";
|
|
2433
2571
|
const userEmail = gitEmail.stdout.toString().trim() || "";
|
|
2434
2572
|
console.log();
|
|
2435
|
-
console.log(
|
|
2573
|
+
console.log(import_picocolors7.default.cyan(" Criando sugestao..."));
|
|
2436
2574
|
const date = new Date().toISOString().split("T")[0];
|
|
2437
2575
|
const body = `## Sugestao
|
|
2438
2576
|
|
|
@@ -2464,11 +2602,11 @@ ${message}
|
|
|
2464
2602
|
stderr: "inherit"
|
|
2465
2603
|
});
|
|
2466
2604
|
if (result.exitCode !== 0) {
|
|
2467
|
-
console.log(
|
|
2605
|
+
console.log(import_picocolors7.default.red(" Erro ao criar issue"));
|
|
2468
2606
|
process.exit(1);
|
|
2469
2607
|
}
|
|
2470
2608
|
console.log();
|
|
2471
|
-
console.log(
|
|
2609
|
+
console.log(import_picocolors7.default.green(" Sugestao enviada! Hugo vai revisar."));
|
|
2472
2610
|
console.log();
|
|
2473
2611
|
}
|
|
2474
2612
|
var PROFILES = {
|
|
@@ -2500,18 +2638,18 @@ var PROFILES = {
|
|
|
2500
2638
|
};
|
|
2501
2639
|
async function onboardDev() {
|
|
2502
2640
|
console.log();
|
|
2503
|
-
console.log(
|
|
2504
|
-
console.log(
|
|
2641
|
+
console.log(import_picocolors7.default.cyan(" Lola - Onboarding"));
|
|
2642
|
+
console.log(import_picocolors7.default.dim(" ================="));
|
|
2505
2643
|
console.log();
|
|
2506
2644
|
if (!existsSync2(LOLA_DIR)) {
|
|
2507
|
-
console.log(
|
|
2645
|
+
console.log(import_picocolors7.default.yellow(" Lola nao instalada. Instalando primeiro..."));
|
|
2508
2646
|
console.log();
|
|
2509
2647
|
await installLola();
|
|
2510
2648
|
console.log();
|
|
2511
2649
|
}
|
|
2512
2650
|
const gitUser = Bun.spawnSync(["git", "config", "user.name"], { stdout: "pipe" });
|
|
2513
2651
|
const defaultName = gitUser.stdout.toString().trim() || "";
|
|
2514
|
-
Ie(
|
|
2652
|
+
Ie(import_picocolors7.default.bgCyan(import_picocolors7.default.black(" Bem-vindo a nimbuslab! ")));
|
|
2515
2653
|
const devName = await he({
|
|
2516
2654
|
message: "Qual seu nome?",
|
|
2517
2655
|
placeholder: "Seu nome",
|
|
@@ -2565,18 +2703,165 @@ lola_profile: ${profile}
|
|
|
2565
2703
|
---
|
|
2566
2704
|
`;
|
|
2567
2705
|
await Bun.write(USER_MEMORY, content);
|
|
2568
|
-
Se(
|
|
2706
|
+
Se(import_picocolors7.default.green("Onboarding concluido!"));
|
|
2569
2707
|
console.log();
|
|
2570
|
-
console.log(
|
|
2571
|
-
console.log(
|
|
2572
|
-
console.log(
|
|
2708
|
+
console.log(import_picocolors7.default.bold(" Resumo:"));
|
|
2709
|
+
console.log(import_picocolors7.default.dim(" Nome: ") + import_picocolors7.default.white(devName));
|
|
2710
|
+
console.log(import_picocolors7.default.dim(" Perfil: ") + import_picocolors7.default.white(PROFILES[profile].label));
|
|
2573
2711
|
console.log();
|
|
2574
|
-
console.log(
|
|
2575
|
-
console.log(
|
|
2576
|
-
console.log(
|
|
2577
|
-
console.log(
|
|
2712
|
+
console.log(import_picocolors7.default.bold(" Proximos passos:"));
|
|
2713
|
+
console.log(import_picocolors7.default.dim(" 1. ") + import_picocolors7.default.white("lola") + import_picocolors7.default.dim(" - Iniciar sessao com a Lola"));
|
|
2714
|
+
console.log(import_picocolors7.default.dim(" 2. ") + import_picocolors7.default.white("nimbus create meu-projeto --fast") + import_picocolors7.default.dim(" - Criar projeto"));
|
|
2715
|
+
console.log(import_picocolors7.default.dim(" 3. ") + import_picocolors7.default.white('lola suggest "sua ideia"') + import_picocolors7.default.dim(" - Sugerir melhoria"));
|
|
2578
2716
|
console.log();
|
|
2579
|
-
console.log(
|
|
2717
|
+
console.log(import_picocolors7.default.dim(" Docs: ~/.lola/README.md"));
|
|
2718
|
+
console.log();
|
|
2719
|
+
}
|
|
2720
|
+
var QUIZ_QUESTIONS = [
|
|
2721
|
+
{
|
|
2722
|
+
question: "Quais sao os 4 valores da nimbuslab?",
|
|
2723
|
+
options: [
|
|
2724
|
+
{ value: "a", label: "Velocidade, Qualidade, Preco, Entrega" },
|
|
2725
|
+
{ value: "b", label: "Cocriacao, Inovacao, Evolucao, Humanizacao" },
|
|
2726
|
+
{ value: "c", label: "Codigo, Design, Marketing, Vendas" },
|
|
2727
|
+
{ value: "d", label: "Agil, Lean, Scrum, Kanban" }
|
|
2728
|
+
],
|
|
2729
|
+
correct: "b",
|
|
2730
|
+
explanation: "Cocriacao (construimos junto), Inovacao (buscamos o novo), Evolucao (aprendizado continuo), Humanizacao (tecnologia a servico das pessoas)."
|
|
2731
|
+
},
|
|
2732
|
+
{
|
|
2733
|
+
question: "Quais sao os 4 pilares da filosofia fast?",
|
|
2734
|
+
options: [
|
|
2735
|
+
{ value: "a", label: "Analise, Planejamento, Execucao, Documentacao" },
|
|
2736
|
+
{ value: "b", label: "Design, Codigo, Teste, Deploy" },
|
|
2737
|
+
{ value: "c", label: "Briefing, Prototipo, Desenvolvimento, Lancamento" },
|
|
2738
|
+
{ value: "d", label: "Discovery, Definition, Development, Delivery" }
|
|
2739
|
+
],
|
|
2740
|
+
correct: "a",
|
|
2741
|
+
explanation: "Filosofia fast: 1. Analise (entender), 2. Planejamento (definir caminho), 3. Execucao (implementar), 4. Documentacao (registrar)."
|
|
2742
|
+
},
|
|
2743
|
+
{
|
|
2744
|
+
question: "Qual package manager a nimbuslab usa como padrao?",
|
|
2745
|
+
options: [
|
|
2746
|
+
{ value: "a", label: "npm" },
|
|
2747
|
+
{ value: "b", label: "yarn" },
|
|
2748
|
+
{ value: "c", label: "pnpm" },
|
|
2749
|
+
{ value: "d", label: "bun" }
|
|
2750
|
+
],
|
|
2751
|
+
correct: "d",
|
|
2752
|
+
explanation: "Bun e o package manager padrao. Mais rapido e com menos dependencias."
|
|
2753
|
+
},
|
|
2754
|
+
{
|
|
2755
|
+
question: "Qual o estilo padrao do shadcn/ui na nimbuslab?",
|
|
2756
|
+
options: [
|
|
2757
|
+
{ value: "a", label: "new-york" },
|
|
2758
|
+
{ value: "b", label: "default" },
|
|
2759
|
+
{ value: "c", label: "minimal" },
|
|
2760
|
+
{ value: "d", label: "custom" }
|
|
2761
|
+
],
|
|
2762
|
+
correct: "b",
|
|
2763
|
+
explanation: "Usamos o estilo 'default' do shadcn/ui. Nunca 'new-york'."
|
|
2764
|
+
},
|
|
2765
|
+
{
|
|
2766
|
+
question: "Em projetos externos (stealth mode), a Lola deve:",
|
|
2767
|
+
options: [
|
|
2768
|
+
{ value: "a", label: "Sempre mencionar a nimbuslab nos commits" },
|
|
2769
|
+
{ value: "b", label: "Usar assinatura 'Co-authored-by: Lola'" },
|
|
2770
|
+
{ value: "c", label: "Nunca mencionar nimbuslab, Lola ou IA" },
|
|
2771
|
+
{ value: "d", label: "Adicionar badge da nimbuslab no README" }
|
|
2772
|
+
],
|
|
2773
|
+
correct: "c",
|
|
2774
|
+
explanation: "Stealth mode: commits sem mencao a nimbuslab/Lola/IA. O cliente nao precisa saber dos bastidores."
|
|
2775
|
+
},
|
|
2776
|
+
{
|
|
2777
|
+
question: "Qual a versao minima do Next.js usada na stack nimbuslab?",
|
|
2778
|
+
options: [
|
|
2779
|
+
{ value: "a", label: "Next.js 13" },
|
|
2780
|
+
{ value: "b", label: "Next.js 14" },
|
|
2781
|
+
{ value: "c", label: "Next.js 15" },
|
|
2782
|
+
{ value: "d", label: "Next.js 16" }
|
|
2783
|
+
],
|
|
2784
|
+
correct: "d",
|
|
2785
|
+
explanation: "Stack atual: Next.js 16+ com App Router e Turbopack."
|
|
2786
|
+
},
|
|
2787
|
+
{
|
|
2788
|
+
question: "Quem pode aprovar e mergear mudancas no repositorio da Lola?",
|
|
2789
|
+
options: [
|
|
2790
|
+
{ value: "a", label: "Qualquer dev da nimbuslab" },
|
|
2791
|
+
{ value: "b", label: "Apenas o Hugo" },
|
|
2792
|
+
{ value: "c", label: "Qualquer pessoa com acesso ao repo" },
|
|
2793
|
+
{ value: "d", label: "A propria Lola via automacao" }
|
|
2794
|
+
],
|
|
2795
|
+
correct: "b",
|
|
2796
|
+
explanation: "Apenas o Hugo pode aprovar e mergear. Devs sugerem via 'lola suggest', Hugo revisa."
|
|
2797
|
+
},
|
|
2798
|
+
{
|
|
2799
|
+
question: "Em commits da nimbuslab, qual o idioma correto?",
|
|
2800
|
+
options: [
|
|
2801
|
+
{ value: "a", label: "Ingles" },
|
|
2802
|
+
{ value: "b", label: "Portugues (BR)" },
|
|
2803
|
+
{ value: "c", label: "Depende do projeto" },
|
|
2804
|
+
{ value: "d", label: "Spanglish" }
|
|
2805
|
+
],
|
|
2806
|
+
correct: "b",
|
|
2807
|
+
explanation: "Commits e PRs em Portugues (BR). Codigo e comentarios em Ingles."
|
|
2808
|
+
}
|
|
2809
|
+
];
|
|
2810
|
+
async function runQuiz() {
|
|
2811
|
+
console.log();
|
|
2812
|
+
console.log(import_picocolors7.default.cyan(" Quiz nimbuslab"));
|
|
2813
|
+
console.log(import_picocolors7.default.dim(" =============="));
|
|
2814
|
+
console.log();
|
|
2815
|
+
console.log(import_picocolors7.default.dim(" Teste seus conhecimentos sobre a nimbuslab!"));
|
|
2816
|
+
console.log(import_picocolors7.default.dim(" 8 perguntas sobre valores, filosofia e stack."));
|
|
2817
|
+
console.log();
|
|
2818
|
+
let score = 0;
|
|
2819
|
+
const results = [];
|
|
2820
|
+
for (let i = 0;i < QUIZ_QUESTIONS.length; i++) {
|
|
2821
|
+
const q2 = QUIZ_QUESTIONS[i];
|
|
2822
|
+
const answer = await ve({
|
|
2823
|
+
message: `${i + 1}. ${q2.question}`,
|
|
2824
|
+
options: q2.options
|
|
2825
|
+
});
|
|
2826
|
+
if (pD(answer)) {
|
|
2827
|
+
xe("Quiz cancelado");
|
|
2828
|
+
process.exit(0);
|
|
2829
|
+
}
|
|
2830
|
+
const isCorrect = answer === q2.correct;
|
|
2831
|
+
if (isCorrect) {
|
|
2832
|
+
score++;
|
|
2833
|
+
console.log(import_picocolors7.default.green(" Correto!"));
|
|
2834
|
+
} else {
|
|
2835
|
+
console.log(import_picocolors7.default.red(" Incorreto."));
|
|
2836
|
+
}
|
|
2837
|
+
console.log(import_picocolors7.default.dim(` ${q2.explanation}`));
|
|
2838
|
+
console.log();
|
|
2839
|
+
results.push({
|
|
2840
|
+
question: q2.question,
|
|
2841
|
+
correct: isCorrect,
|
|
2842
|
+
explanation: q2.explanation
|
|
2843
|
+
});
|
|
2844
|
+
}
|
|
2845
|
+
const percentage = Math.round(score / QUIZ_QUESTIONS.length * 100);
|
|
2846
|
+
const passed = percentage >= 75;
|
|
2847
|
+
console.log(import_picocolors7.default.bold(" Resultado:"));
|
|
2848
|
+
console.log();
|
|
2849
|
+
if (passed) {
|
|
2850
|
+
console.log(import_picocolors7.default.green(` ${score}/${QUIZ_QUESTIONS.length} (${percentage}%) - Aprovado!`));
|
|
2851
|
+
console.log();
|
|
2852
|
+
if (percentage === 100) {
|
|
2853
|
+
console.log(import_picocolors7.default.cyan(" Perfeito! Voce conhece bem a nimbuslab."));
|
|
2854
|
+
} else {
|
|
2855
|
+
console.log(import_picocolors7.default.cyan(" Muito bem! Voce esta pronto para trabalhar."));
|
|
2856
|
+
}
|
|
2857
|
+
} else {
|
|
2858
|
+
console.log(import_picocolors7.default.yellow(` ${score}/${QUIZ_QUESTIONS.length} (${percentage}%) - Precisa revisar`));
|
|
2859
|
+
console.log();
|
|
2860
|
+
console.log(import_picocolors7.default.dim(" Revise os conceitos em:"));
|
|
2861
|
+
console.log(import_picocolors7.default.dim(" ~/.lola/core/values.md"));
|
|
2862
|
+
console.log(import_picocolors7.default.dim(" ~/.lola/core/philosophy.md"));
|
|
2863
|
+
console.log(import_picocolors7.default.dim(" ~/.lola/modules/stack.md"));
|
|
2864
|
+
}
|
|
2580
2865
|
console.log();
|
|
2581
2866
|
}
|
|
2582
2867
|
async function lola(args) {
|
|
@@ -2585,39 +2870,43 @@ async function lola(args) {
|
|
|
2585
2870
|
await installLola();
|
|
2586
2871
|
} else if (subcommand === "onboard") {
|
|
2587
2872
|
await onboardDev();
|
|
2873
|
+
} else if (subcommand === "quiz") {
|
|
2874
|
+
await runQuiz();
|
|
2588
2875
|
} else if (subcommand === "suggest") {
|
|
2589
2876
|
const message = args.slice(1).join(" ");
|
|
2590
2877
|
await suggestImprovement(message);
|
|
2591
2878
|
} else if (subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
|
|
2592
2879
|
showLolaHelp();
|
|
2593
2880
|
} else {
|
|
2594
|
-
console.log(
|
|
2881
|
+
console.log(import_picocolors7.default.red(` Subcomando desconhecido: ${subcommand}`));
|
|
2595
2882
|
showLolaHelp();
|
|
2596
2883
|
process.exit(1);
|
|
2597
2884
|
}
|
|
2598
2885
|
}
|
|
2599
2886
|
function showLolaHelp() {
|
|
2600
2887
|
console.log();
|
|
2601
|
-
console.log(
|
|
2888
|
+
console.log(import_picocolors7.default.bold(" Lola - Code Agent da nimbuslab"));
|
|
2602
2889
|
console.log();
|
|
2603
|
-
console.log(
|
|
2890
|
+
console.log(import_picocolors7.default.bold(" Uso:") + " nimbus lola [subcomando]");
|
|
2604
2891
|
console.log();
|
|
2605
|
-
console.log(
|
|
2606
|
-
console.log(
|
|
2607
|
-
console.log(
|
|
2608
|
-
console.log(
|
|
2609
|
-
console.log(
|
|
2610
|
-
console.log(
|
|
2892
|
+
console.log(import_picocolors7.default.bold(" Subcomandos:"));
|
|
2893
|
+
console.log(import_picocolors7.default.dim(" install ") + import_picocolors7.default.white("Instalar/atualizar Lola"));
|
|
2894
|
+
console.log(import_picocolors7.default.dim(" sync ") + import_picocolors7.default.white("Alias para install"));
|
|
2895
|
+
console.log(import_picocolors7.default.dim(" onboard ") + import_picocolors7.default.white("Configurar perfil (novos devs)"));
|
|
2896
|
+
console.log(import_picocolors7.default.dim(" quiz ") + import_picocolors7.default.white("Quiz sobre a nimbuslab"));
|
|
2897
|
+
console.log(import_picocolors7.default.dim(' suggest "msg" ') + import_picocolors7.default.white("Sugerir melhoria (cria issue)"));
|
|
2898
|
+
console.log(import_picocolors7.default.dim(" help ") + import_picocolors7.default.white("Mostrar esta ajuda"));
|
|
2611
2899
|
console.log();
|
|
2612
|
-
console.log(
|
|
2613
|
-
console.log(
|
|
2614
|
-
console.log(
|
|
2615
|
-
console.log(
|
|
2900
|
+
console.log(import_picocolors7.default.bold(" Exemplos:"));
|
|
2901
|
+
console.log(import_picocolors7.default.dim(" $ nimbus lola install"));
|
|
2902
|
+
console.log(import_picocolors7.default.dim(" $ nimbus lola onboard"));
|
|
2903
|
+
console.log(import_picocolors7.default.dim(" $ nimbus lola quiz"));
|
|
2904
|
+
console.log(import_picocolors7.default.dim(' $ nimbus lola suggest "adicionar suporte a X"'));
|
|
2616
2905
|
console.log();
|
|
2617
2906
|
}
|
|
2618
2907
|
|
|
2619
2908
|
// src/index.ts
|
|
2620
|
-
var
|
|
2909
|
+
var PACKAGE_NAME2 = "@nimbuslab/cli";
|
|
2621
2910
|
var pkg = await Promise.resolve().then(() => __toESM(require_package(), 1));
|
|
2622
2911
|
var CURRENT_VERSION = pkg.version;
|
|
2623
2912
|
var LOGO = `
|
|
@@ -2631,7 +2920,7 @@ async function checkForUpdates() {
|
|
|
2631
2920
|
try {
|
|
2632
2921
|
const controller = new AbortController;
|
|
2633
2922
|
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
2634
|
-
const res = await fetch(`https://registry.npmjs.org/${
|
|
2923
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME2}/latest`, {
|
|
2635
2924
|
signal: controller.signal
|
|
2636
2925
|
});
|
|
2637
2926
|
clearTimeout(timeout);
|
|
@@ -2650,23 +2939,23 @@ async function checkForUpdates() {
|
|
|
2650
2939
|
function showUpdateNotice(latestVersion) {
|
|
2651
2940
|
const current = CURRENT_VERSION;
|
|
2652
2941
|
const latest = latestVersion;
|
|
2653
|
-
const command =
|
|
2654
|
-
const line1 = `
|
|
2655
|
-
const line2 = `
|
|
2942
|
+
const command = "nimbus update";
|
|
2943
|
+
const line1 = ` Nova vers\xE3o dispon\xEDvel: ${current} \u2192 ${latest}`;
|
|
2944
|
+
const line2 = ` Atualize com: ${command}`;
|
|
2656
2945
|
const maxLen = Math.max(line1.length, line2.length);
|
|
2657
2946
|
const border = "\u2500".repeat(maxLen + 2);
|
|
2658
|
-
console.log(
|
|
2659
|
-
console.log(
|
|
2660
|
-
console.log(
|
|
2661
|
-
console.log(
|
|
2947
|
+
console.log(import_picocolors8.default.yellow(` \u250C${border}\u2510`));
|
|
2948
|
+
console.log(import_picocolors8.default.yellow(` \u2502`) + import_picocolors8.default.white(line1.padEnd(maxLen + 1)) + import_picocolors8.default.yellow(`\u2502`));
|
|
2949
|
+
console.log(import_picocolors8.default.yellow(` \u2502`) + import_picocolors8.default.cyan(line2.padEnd(maxLen + 1)) + import_picocolors8.default.yellow(`\u2502`));
|
|
2950
|
+
console.log(import_picocolors8.default.yellow(` \u2514${border}\u2518`));
|
|
2662
2951
|
console.log();
|
|
2663
2952
|
}
|
|
2664
2953
|
async function main() {
|
|
2665
2954
|
const args = process.argv.slice(2);
|
|
2666
2955
|
const command = args[0];
|
|
2667
|
-
console.log(
|
|
2668
|
-
console.log(
|
|
2669
|
-
console.log(
|
|
2956
|
+
console.log(import_picocolors8.default.cyan(LOGO));
|
|
2957
|
+
console.log(import_picocolors8.default.white(" nimbuslab CLI"));
|
|
2958
|
+
console.log(import_picocolors8.default.dim(" Create awesome projects"));
|
|
2670
2959
|
console.log();
|
|
2671
2960
|
const latestVersion = await checkForUpdates();
|
|
2672
2961
|
if (latestVersion) {
|
|
@@ -2678,6 +2967,8 @@ async function main() {
|
|
|
2678
2967
|
await analyze(args.slice(1));
|
|
2679
2968
|
} else if (command === "upgrade") {
|
|
2680
2969
|
await upgrade(args.slice(1));
|
|
2970
|
+
} else if (command === "update") {
|
|
2971
|
+
await update(args.slice(1));
|
|
2681
2972
|
} else if (command === "lola") {
|
|
2682
2973
|
await lola(args.slice(1));
|
|
2683
2974
|
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
@@ -2685,58 +2976,64 @@ async function main() {
|
|
|
2685
2976
|
} else if (command === "version" || command === "--version" || command === "-v") {
|
|
2686
2977
|
showVersion();
|
|
2687
2978
|
} else {
|
|
2688
|
-
console.log(
|
|
2979
|
+
console.log(import_picocolors8.default.red(`Comando desconhecido: ${command}`));
|
|
2689
2980
|
showHelp();
|
|
2690
2981
|
process.exit(1);
|
|
2691
2982
|
}
|
|
2692
2983
|
}
|
|
2693
2984
|
function showHelp() {
|
|
2694
2985
|
console.log(`
|
|
2695
|
-
${
|
|
2986
|
+
${import_picocolors8.default.bold("Uso:")} nimbus [comando] [op\xE7\xF5es]
|
|
2696
2987
|
|
|
2697
|
-
${
|
|
2698
|
-
create [
|
|
2699
|
-
analyze [dir]
|
|
2700
|
-
upgrade [
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2988
|
+
${import_picocolors8.default.bold("Comandos:")}
|
|
2989
|
+
create [nome] Criar novo projeto
|
|
2990
|
+
analyze [dir] Analisar stack do projeto
|
|
2991
|
+
upgrade [alvo] Atualizar depend\xEAncias
|
|
2992
|
+
update [vers\xE3o] Atualizar o CLI
|
|
2993
|
+
lola [a\xE7\xE3o] Lola - Code Agent
|
|
2994
|
+
help Mostrar esta ajuda
|
|
2995
|
+
version Mostrar vers\xE3o
|
|
2704
2996
|
|
|
2705
|
-
${
|
|
2997
|
+
${import_picocolors8.default.bold("Templates:")}
|
|
2706
2998
|
--landing Landing page (Next.js 16 + Tailwind 4 + shadcn)
|
|
2707
2999
|
--app Web app (Landing + Better Auth + Drizzle)
|
|
2708
3000
|
--turborepo Monorepo (Turborepo + apps/packages)
|
|
2709
3001
|
|
|
2710
|
-
${
|
|
2711
|
-
analyze .
|
|
2712
|
-
analyze --json Output
|
|
2713
|
-
upgrade --plan
|
|
2714
|
-
upgrade next
|
|
2715
|
-
upgrade tailwind
|
|
3002
|
+
${import_picocolors8.default.bold("Analyze & Upgrade:")}
|
|
3003
|
+
analyze . Detectar stack e mostrar recomenda\xE7\xF5es
|
|
3004
|
+
analyze --json Output em JSON
|
|
3005
|
+
upgrade --plan Mostrar plano de upgrade
|
|
3006
|
+
upgrade next Atualizar Next.js
|
|
3007
|
+
upgrade tailwind Atualizar Tailwind CSS
|
|
3008
|
+
|
|
3009
|
+
${import_picocolors8.default.bold("Update (CLI):")}
|
|
3010
|
+
update Atualizar para \xFAltima vers\xE3o
|
|
3011
|
+
update 0.11.0 Instalar vers\xE3o espec\xEDfica
|
|
3012
|
+
update --list Listar vers\xF5es dispon\xEDveis
|
|
2716
3013
|
|
|
2717
|
-
${
|
|
2718
|
-
-y, --yes
|
|
2719
|
-
--no-git
|
|
2720
|
-
--no-install
|
|
2721
|
-
--template <url>
|
|
3014
|
+
${import_picocolors8.default.bold("Op\xE7\xF5es:")}
|
|
3015
|
+
-y, --yes Aceitar padr\xF5es
|
|
3016
|
+
--no-git N\xE3o inicializar Git
|
|
3017
|
+
--no-install N\xE3o instalar depend\xEAncias
|
|
3018
|
+
--template <url> Usar template customizado
|
|
2722
3019
|
|
|
2723
|
-
${
|
|
2724
|
-
lola install
|
|
2725
|
-
lola suggest
|
|
3020
|
+
${import_picocolors8.default.bold("Lola (Code Agent):")}
|
|
3021
|
+
lola install Instalar/atualizar Lola
|
|
3022
|
+
lola suggest Sugerir melhoria (cria issue)
|
|
2726
3023
|
|
|
2727
|
-
${
|
|
2728
|
-
${
|
|
2729
|
-
${
|
|
2730
|
-
${
|
|
2731
|
-
${
|
|
2732
|
-
${
|
|
2733
|
-
${
|
|
3024
|
+
${import_picocolors8.default.bold("Exemplos:")}
|
|
3025
|
+
${import_picocolors8.default.dim("$")} nimbus create my-landing --landing
|
|
3026
|
+
${import_picocolors8.default.dim("$")} nimbus create my-app --app
|
|
3027
|
+
${import_picocolors8.default.dim("$")} nimbus analyze ./my-project
|
|
3028
|
+
${import_picocolors8.default.dim("$")} nimbus upgrade --plan
|
|
3029
|
+
${import_picocolors8.default.dim("$")} nimbus update
|
|
3030
|
+
${import_picocolors8.default.dim("$")} nimbus lola install
|
|
2734
3031
|
`);
|
|
2735
3032
|
}
|
|
2736
3033
|
function showVersion() {
|
|
2737
|
-
console.log(`${
|
|
3034
|
+
console.log(`${PACKAGE_NAME2} v${CURRENT_VERSION}`);
|
|
2738
3035
|
}
|
|
2739
3036
|
main().catch((err) => {
|
|
2740
|
-
console.error(
|
|
3037
|
+
console.error(import_picocolors8.default.red("Erro:"), err.message);
|
|
2741
3038
|
process.exit(1);
|
|
2742
3039
|
});
|
package/package.json
CHANGED
package/src/commands/lola.ts
CHANGED
|
@@ -293,6 +293,173 @@ lola_profile: ${profile}
|
|
|
293
293
|
console.log()
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
+
// Quiz sobre a nimbuslab
|
|
297
|
+
interface QuizQuestion {
|
|
298
|
+
question: string
|
|
299
|
+
options: { value: string; label: string }[]
|
|
300
|
+
correct: string
|
|
301
|
+
explanation: string
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const QUIZ_QUESTIONS: QuizQuestion[] = [
|
|
305
|
+
{
|
|
306
|
+
question: "Quais sao os 4 valores da nimbuslab?",
|
|
307
|
+
options: [
|
|
308
|
+
{ value: "a", label: "Velocidade, Qualidade, Preco, Entrega" },
|
|
309
|
+
{ value: "b", label: "Cocriacao, Inovacao, Evolucao, Humanizacao" },
|
|
310
|
+
{ value: "c", label: "Codigo, Design, Marketing, Vendas" },
|
|
311
|
+
{ value: "d", label: "Agil, Lean, Scrum, Kanban" },
|
|
312
|
+
],
|
|
313
|
+
correct: "b",
|
|
314
|
+
explanation: "Cocriacao (construimos junto), Inovacao (buscamos o novo), Evolucao (aprendizado continuo), Humanizacao (tecnologia a servico das pessoas).",
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
question: "Quais sao os 4 pilares da filosofia fast?",
|
|
318
|
+
options: [
|
|
319
|
+
{ value: "a", label: "Analise, Planejamento, Execucao, Documentacao" },
|
|
320
|
+
{ value: "b", label: "Design, Codigo, Teste, Deploy" },
|
|
321
|
+
{ value: "c", label: "Briefing, Prototipo, Desenvolvimento, Lancamento" },
|
|
322
|
+
{ value: "d", label: "Discovery, Definition, Development, Delivery" },
|
|
323
|
+
],
|
|
324
|
+
correct: "a",
|
|
325
|
+
explanation: "Filosofia fast: 1. Analise (entender), 2. Planejamento (definir caminho), 3. Execucao (implementar), 4. Documentacao (registrar).",
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
question: "Qual package manager a nimbuslab usa como padrao?",
|
|
329
|
+
options: [
|
|
330
|
+
{ value: "a", label: "npm" },
|
|
331
|
+
{ value: "b", label: "yarn" },
|
|
332
|
+
{ value: "c", label: "pnpm" },
|
|
333
|
+
{ value: "d", label: "bun" },
|
|
334
|
+
],
|
|
335
|
+
correct: "d",
|
|
336
|
+
explanation: "Bun e o package manager padrao. Mais rapido e com menos dependencias.",
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
question: "Qual o estilo padrao do shadcn/ui na nimbuslab?",
|
|
340
|
+
options: [
|
|
341
|
+
{ value: "a", label: "new-york" },
|
|
342
|
+
{ value: "b", label: "default" },
|
|
343
|
+
{ value: "c", label: "minimal" },
|
|
344
|
+
{ value: "d", label: "custom" },
|
|
345
|
+
],
|
|
346
|
+
correct: "b",
|
|
347
|
+
explanation: "Usamos o estilo 'default' do shadcn/ui. Nunca 'new-york'.",
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
question: "Em projetos externos (stealth mode), a Lola deve:",
|
|
351
|
+
options: [
|
|
352
|
+
{ value: "a", label: "Sempre mencionar a nimbuslab nos commits" },
|
|
353
|
+
{ value: "b", label: "Usar assinatura 'Co-authored-by: Lola'" },
|
|
354
|
+
{ value: "c", label: "Nunca mencionar nimbuslab, Lola ou IA" },
|
|
355
|
+
{ value: "d", label: "Adicionar badge da nimbuslab no README" },
|
|
356
|
+
],
|
|
357
|
+
correct: "c",
|
|
358
|
+
explanation: "Stealth mode: commits sem mencao a nimbuslab/Lola/IA. O cliente nao precisa saber dos bastidores.",
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
question: "Qual a versao minima do Next.js usada na stack nimbuslab?",
|
|
362
|
+
options: [
|
|
363
|
+
{ value: "a", label: "Next.js 13" },
|
|
364
|
+
{ value: "b", label: "Next.js 14" },
|
|
365
|
+
{ value: "c", label: "Next.js 15" },
|
|
366
|
+
{ value: "d", label: "Next.js 16" },
|
|
367
|
+
],
|
|
368
|
+
correct: "d",
|
|
369
|
+
explanation: "Stack atual: Next.js 16+ com App Router e Turbopack.",
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
question: "Quem pode aprovar e mergear mudancas no repositorio da Lola?",
|
|
373
|
+
options: [
|
|
374
|
+
{ value: "a", label: "Qualquer dev da nimbuslab" },
|
|
375
|
+
{ value: "b", label: "Apenas o Hugo" },
|
|
376
|
+
{ value: "c", label: "Qualquer pessoa com acesso ao repo" },
|
|
377
|
+
{ value: "d", label: "A propria Lola via automacao" },
|
|
378
|
+
],
|
|
379
|
+
correct: "b",
|
|
380
|
+
explanation: "Apenas o Hugo pode aprovar e mergear. Devs sugerem via 'lola suggest', Hugo revisa.",
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
question: "Em commits da nimbuslab, qual o idioma correto?",
|
|
384
|
+
options: [
|
|
385
|
+
{ value: "a", label: "Ingles" },
|
|
386
|
+
{ value: "b", label: "Portugues (BR)" },
|
|
387
|
+
{ value: "c", label: "Depende do projeto" },
|
|
388
|
+
{ value: "d", label: "Spanglish" },
|
|
389
|
+
],
|
|
390
|
+
correct: "b",
|
|
391
|
+
explanation: "Commits e PRs em Portugues (BR). Codigo e comentarios em Ingles.",
|
|
392
|
+
},
|
|
393
|
+
]
|
|
394
|
+
|
|
395
|
+
async function runQuiz(): Promise<void> {
|
|
396
|
+
console.log()
|
|
397
|
+
console.log(pc.cyan(" Quiz nimbuslab"))
|
|
398
|
+
console.log(pc.dim(" =============="))
|
|
399
|
+
console.log()
|
|
400
|
+
console.log(pc.dim(" Teste seus conhecimentos sobre a nimbuslab!"))
|
|
401
|
+
console.log(pc.dim(" 8 perguntas sobre valores, filosofia e stack."))
|
|
402
|
+
console.log()
|
|
403
|
+
|
|
404
|
+
let score = 0
|
|
405
|
+
const results: { question: string; correct: boolean; explanation: string }[] = []
|
|
406
|
+
|
|
407
|
+
for (let i = 0; i < QUIZ_QUESTIONS.length; i++) {
|
|
408
|
+
const q = QUIZ_QUESTIONS[i]!
|
|
409
|
+
|
|
410
|
+
const answer = await p.select({
|
|
411
|
+
message: `${i + 1}. ${q.question}`,
|
|
412
|
+
options: q.options,
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
if (p.isCancel(answer)) {
|
|
416
|
+
p.cancel("Quiz cancelado")
|
|
417
|
+
process.exit(0)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const isCorrect = answer === q.correct
|
|
421
|
+
if (isCorrect) {
|
|
422
|
+
score++
|
|
423
|
+
console.log(pc.green(" Correto!"))
|
|
424
|
+
} else {
|
|
425
|
+
console.log(pc.red(" Incorreto."))
|
|
426
|
+
}
|
|
427
|
+
console.log(pc.dim(` ${q.explanation}`))
|
|
428
|
+
console.log()
|
|
429
|
+
|
|
430
|
+
results.push({
|
|
431
|
+
question: q.question,
|
|
432
|
+
correct: isCorrect,
|
|
433
|
+
explanation: q.explanation,
|
|
434
|
+
})
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Resultado final
|
|
438
|
+
const percentage = Math.round((score / QUIZ_QUESTIONS.length) * 100)
|
|
439
|
+
const passed = percentage >= 75
|
|
440
|
+
|
|
441
|
+
console.log(pc.bold(" Resultado:"))
|
|
442
|
+
console.log()
|
|
443
|
+
|
|
444
|
+
if (passed) {
|
|
445
|
+
console.log(pc.green(` ${score}/${QUIZ_QUESTIONS.length} (${percentage}%) - Aprovado!`))
|
|
446
|
+
console.log()
|
|
447
|
+
if (percentage === 100) {
|
|
448
|
+
console.log(pc.cyan(" Perfeito! Voce conhece bem a nimbuslab."))
|
|
449
|
+
} else {
|
|
450
|
+
console.log(pc.cyan(" Muito bem! Voce esta pronto para trabalhar."))
|
|
451
|
+
}
|
|
452
|
+
} else {
|
|
453
|
+
console.log(pc.yellow(` ${score}/${QUIZ_QUESTIONS.length} (${percentage}%) - Precisa revisar`))
|
|
454
|
+
console.log()
|
|
455
|
+
console.log(pc.dim(" Revise os conceitos em:"))
|
|
456
|
+
console.log(pc.dim(" ~/.lola/core/values.md"))
|
|
457
|
+
console.log(pc.dim(" ~/.lola/core/philosophy.md"))
|
|
458
|
+
console.log(pc.dim(" ~/.lola/modules/stack.md"))
|
|
459
|
+
}
|
|
460
|
+
console.log()
|
|
461
|
+
}
|
|
462
|
+
|
|
296
463
|
export async function lola(args: string[]) {
|
|
297
464
|
const subcommand = args[0]
|
|
298
465
|
|
|
@@ -300,6 +467,8 @@ export async function lola(args: string[]) {
|
|
|
300
467
|
await installLola()
|
|
301
468
|
} else if (subcommand === "onboard") {
|
|
302
469
|
await onboardDev()
|
|
470
|
+
} else if (subcommand === "quiz") {
|
|
471
|
+
await runQuiz()
|
|
303
472
|
} else if (subcommand === "suggest") {
|
|
304
473
|
const message = args.slice(1).join(" ")
|
|
305
474
|
await suggestImprovement(message)
|
|
@@ -322,12 +491,14 @@ function showLolaHelp() {
|
|
|
322
491
|
console.log(pc.dim(" install ") + pc.white("Instalar/atualizar Lola"))
|
|
323
492
|
console.log(pc.dim(" sync ") + pc.white("Alias para install"))
|
|
324
493
|
console.log(pc.dim(" onboard ") + pc.white("Configurar perfil (novos devs)"))
|
|
494
|
+
console.log(pc.dim(" quiz ") + pc.white("Quiz sobre a nimbuslab"))
|
|
325
495
|
console.log(pc.dim(" suggest \"msg\" ") + pc.white("Sugerir melhoria (cria issue)"))
|
|
326
496
|
console.log(pc.dim(" help ") + pc.white("Mostrar esta ajuda"))
|
|
327
497
|
console.log()
|
|
328
498
|
console.log(pc.bold(" Exemplos:"))
|
|
329
499
|
console.log(pc.dim(" $ nimbus lola install"))
|
|
330
500
|
console.log(pc.dim(" $ nimbus lola onboard"))
|
|
501
|
+
console.log(pc.dim(" $ nimbus lola quiz"))
|
|
331
502
|
console.log(pc.dim(" $ nimbus lola suggest \"adicionar suporte a X\""))
|
|
332
503
|
console.log()
|
|
333
504
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import * as p from "@clack/prompts"
|
|
2
|
+
import pc from "picocolors"
|
|
3
|
+
import { execSync, spawnSync } from "child_process"
|
|
4
|
+
|
|
5
|
+
const PACKAGE_NAME = "@nimbuslab/cli"
|
|
6
|
+
|
|
7
|
+
async function getAvailableVersions(): Promise<string[]> {
|
|
8
|
+
try {
|
|
9
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`)
|
|
10
|
+
if (!res.ok) return []
|
|
11
|
+
const data = await res.json() as { versions?: Record<string, unknown> }
|
|
12
|
+
return Object.keys(data.versions || {}).reverse()
|
|
13
|
+
} catch {
|
|
14
|
+
return []
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function getLatestVersion(): Promise<string | null> {
|
|
19
|
+
try {
|
|
20
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`)
|
|
21
|
+
if (!res.ok) return null
|
|
22
|
+
const data = await res.json() as { version?: string }
|
|
23
|
+
return data.version || null
|
|
24
|
+
} catch {
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getCurrentVersion(): string {
|
|
30
|
+
try {
|
|
31
|
+
const result = spawnSync("npm", ["ls", "-g", PACKAGE_NAME, "--json"], {
|
|
32
|
+
encoding: "utf-8",
|
|
33
|
+
shell: true,
|
|
34
|
+
})
|
|
35
|
+
if (result.stdout) {
|
|
36
|
+
const data = JSON.parse(result.stdout)
|
|
37
|
+
return data.dependencies?.[PACKAGE_NAME]?.version || "unknown"
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
// ignore
|
|
41
|
+
}
|
|
42
|
+
return "unknown"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function update(args: string[]) {
|
|
46
|
+
const flag = args[0]
|
|
47
|
+
|
|
48
|
+
// nimbus update --list
|
|
49
|
+
if (flag === "--list" || flag === "-l") {
|
|
50
|
+
p.intro(pc.cyan("Versões disponíveis"))
|
|
51
|
+
|
|
52
|
+
const spinner = p.spinner()
|
|
53
|
+
spinner.start("Buscando versões...")
|
|
54
|
+
|
|
55
|
+
const versions = await getAvailableVersions()
|
|
56
|
+
spinner.stop("Versões encontradas")
|
|
57
|
+
|
|
58
|
+
if (versions.length === 0) {
|
|
59
|
+
p.log.error("Não foi possível buscar as versões")
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const current = getCurrentVersion()
|
|
64
|
+
|
|
65
|
+
console.log()
|
|
66
|
+
console.log(pc.bold("Últimas 10 versões:"))
|
|
67
|
+
versions.slice(0, 10).forEach((v, i) => {
|
|
68
|
+
const isCurrent = v === current
|
|
69
|
+
const prefix = isCurrent ? pc.green("→ ") : " "
|
|
70
|
+
const suffix = isCurrent ? pc.dim(" (instalada)") : ""
|
|
71
|
+
const isLatest = i === 0 ? pc.yellow(" (latest)") : ""
|
|
72
|
+
console.log(`${prefix}${v}${suffix}${isLatest}`)
|
|
73
|
+
})
|
|
74
|
+
console.log()
|
|
75
|
+
console.log(pc.dim(`Total: ${versions.length} versões`))
|
|
76
|
+
console.log(pc.dim(`Instalar versão específica: nimbus update <versão>`))
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// nimbus update [version]
|
|
81
|
+
const targetVersion = flag || "latest"
|
|
82
|
+
const isSpecificVersion = flag && flag !== "latest"
|
|
83
|
+
|
|
84
|
+
p.intro(pc.cyan(`Atualizando ${PACKAGE_NAME}`))
|
|
85
|
+
|
|
86
|
+
const spinner = p.spinner()
|
|
87
|
+
|
|
88
|
+
// Verificar versão atual
|
|
89
|
+
spinner.start("Verificando versão atual...")
|
|
90
|
+
const currentVersion = getCurrentVersion()
|
|
91
|
+
spinner.stop(`Versão atual: ${currentVersion}`)
|
|
92
|
+
|
|
93
|
+
// Verificar versão alvo
|
|
94
|
+
if (!isSpecificVersion) {
|
|
95
|
+
spinner.start("Verificando última versão...")
|
|
96
|
+
const latest = await getLatestVersion()
|
|
97
|
+
spinner.stop(`Última versão: ${latest || "desconhecida"}`)
|
|
98
|
+
|
|
99
|
+
if (latest && latest === currentVersion) {
|
|
100
|
+
p.log.success("Você já está na última versão!")
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Confirmar
|
|
106
|
+
const versionText = isSpecificVersion ? targetVersion : "latest"
|
|
107
|
+
const confirmUpdate = await p.confirm({
|
|
108
|
+
message: `Atualizar para ${versionText}?`,
|
|
109
|
+
initialValue: true,
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
if (p.isCancel(confirmUpdate) || !confirmUpdate) {
|
|
113
|
+
p.cancel("Atualização cancelada")
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Executar update
|
|
118
|
+
spinner.start("Atualizando...")
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
const packageSpec = isSpecificVersion
|
|
122
|
+
? `${PACKAGE_NAME}@${targetVersion}`
|
|
123
|
+
: PACKAGE_NAME
|
|
124
|
+
|
|
125
|
+
// Usar npm para instalação global (mais estável que bun)
|
|
126
|
+
execSync(`npm install -g ${packageSpec}`, {
|
|
127
|
+
stdio: "pipe",
|
|
128
|
+
encoding: "utf-8",
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
spinner.stop("Atualização concluída!")
|
|
132
|
+
|
|
133
|
+
// Verificar nova versão
|
|
134
|
+
const newVersion = getCurrentVersion()
|
|
135
|
+
|
|
136
|
+
p.log.success(`${PACKAGE_NAME} atualizado: ${currentVersion} → ${newVersion}`)
|
|
137
|
+
p.outro(pc.green("Pronto!"))
|
|
138
|
+
} catch (error) {
|
|
139
|
+
spinner.stop("Erro na atualização")
|
|
140
|
+
|
|
141
|
+
const err = error as Error & { stderr?: string }
|
|
142
|
+
p.log.error("Falha ao atualizar")
|
|
143
|
+
|
|
144
|
+
if (err.stderr) {
|
|
145
|
+
console.log(pc.dim(err.stderr))
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
console.log()
|
|
149
|
+
console.log(pc.yellow("Tente manualmente:"))
|
|
150
|
+
console.log(pc.cyan(` npm install -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`))
|
|
151
|
+
}
|
|
152
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import pc from "picocolors"
|
|
|
5
5
|
import { create } from "./commands/create"
|
|
6
6
|
import { analyze } from "./commands/analyze"
|
|
7
7
|
import { upgrade } from "./commands/upgrade"
|
|
8
|
+
import { update } from "./commands/update"
|
|
8
9
|
import { lola } from "./commands/lola"
|
|
9
10
|
|
|
10
11
|
const PACKAGE_NAME = "@nimbuslab/cli"
|
|
@@ -48,10 +49,10 @@ async function checkForUpdates(): Promise<string | null> {
|
|
|
48
49
|
function showUpdateNotice(latestVersion: string) {
|
|
49
50
|
const current = CURRENT_VERSION
|
|
50
51
|
const latest = latestVersion
|
|
51
|
-
const command =
|
|
52
|
+
const command = "nimbus update"
|
|
52
53
|
|
|
53
|
-
const line1 = `
|
|
54
|
-
const line2 = `
|
|
54
|
+
const line1 = ` Nova versão disponível: ${current} → ${latest}`
|
|
55
|
+
const line2 = ` Atualize com: ${command}`
|
|
55
56
|
|
|
56
57
|
const maxLen = Math.max(line1.length, line2.length)
|
|
57
58
|
const border = "─".repeat(maxLen + 2)
|
|
@@ -84,6 +85,8 @@ async function main() {
|
|
|
84
85
|
await analyze(args.slice(1))
|
|
85
86
|
} else if (command === "upgrade") {
|
|
86
87
|
await upgrade(args.slice(1))
|
|
88
|
+
} else if (command === "update") {
|
|
89
|
+
await update(args.slice(1))
|
|
87
90
|
} else if (command === "lola") {
|
|
88
91
|
await lola(args.slice(1))
|
|
89
92
|
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
@@ -91,7 +94,7 @@ async function main() {
|
|
|
91
94
|
} else if (command === "version" || command === "--version" || command === "-v") {
|
|
92
95
|
showVersion()
|
|
93
96
|
} else {
|
|
94
|
-
console.log(pc.red(`
|
|
97
|
+
console.log(pc.red(`Comando desconhecido: ${command}`))
|
|
95
98
|
showHelp()
|
|
96
99
|
process.exit(1)
|
|
97
100
|
}
|
|
@@ -99,15 +102,16 @@ async function main() {
|
|
|
99
102
|
|
|
100
103
|
function showHelp() {
|
|
101
104
|
console.log(`
|
|
102
|
-
${pc.bold("
|
|
105
|
+
${pc.bold("Uso:")} nimbus [comando] [opções]
|
|
103
106
|
|
|
104
|
-
${pc.bold("
|
|
105
|
-
create [
|
|
106
|
-
analyze [dir]
|
|
107
|
-
upgrade [
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
${pc.bold("Comandos:")}
|
|
108
|
+
create [nome] Criar novo projeto
|
|
109
|
+
analyze [dir] Analisar stack do projeto
|
|
110
|
+
upgrade [alvo] Atualizar dependências
|
|
111
|
+
update [versão] Atualizar o CLI
|
|
112
|
+
lola [ação] Lola - Code Agent
|
|
113
|
+
help Mostrar esta ajuda
|
|
114
|
+
version Mostrar versão
|
|
111
115
|
|
|
112
116
|
${pc.bold("Templates:")}
|
|
113
117
|
--landing Landing page (Next.js 16 + Tailwind 4 + shadcn)
|
|
@@ -115,29 +119,34 @@ ${pc.bold("Templates:")}
|
|
|
115
119
|
--turborepo Monorepo (Turborepo + apps/packages)
|
|
116
120
|
|
|
117
121
|
${pc.bold("Analyze & Upgrade:")}
|
|
118
|
-
analyze .
|
|
119
|
-
analyze --json Output
|
|
120
|
-
upgrade --plan
|
|
121
|
-
upgrade next
|
|
122
|
-
upgrade tailwind
|
|
123
|
-
|
|
124
|
-
${pc.bold("
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
--
|
|
128
|
-
|
|
122
|
+
analyze . Detectar stack e mostrar recomendações
|
|
123
|
+
analyze --json Output em JSON
|
|
124
|
+
upgrade --plan Mostrar plano de upgrade
|
|
125
|
+
upgrade next Atualizar Next.js
|
|
126
|
+
upgrade tailwind Atualizar Tailwind CSS
|
|
127
|
+
|
|
128
|
+
${pc.bold("Update (CLI):")}
|
|
129
|
+
update Atualizar para última versão
|
|
130
|
+
update 0.11.0 Instalar versão específica
|
|
131
|
+
update --list Listar versões disponíveis
|
|
132
|
+
|
|
133
|
+
${pc.bold("Opções:")}
|
|
134
|
+
-y, --yes Aceitar padrões
|
|
135
|
+
--no-git Não inicializar Git
|
|
136
|
+
--no-install Não instalar dependências
|
|
137
|
+
--template <url> Usar template customizado
|
|
129
138
|
|
|
130
139
|
${pc.bold("Lola (Code Agent):")}
|
|
131
|
-
lola install
|
|
132
|
-
lola suggest
|
|
140
|
+
lola install Instalar/atualizar Lola
|
|
141
|
+
lola suggest Sugerir melhoria (cria issue)
|
|
133
142
|
|
|
134
|
-
${pc.bold("
|
|
143
|
+
${pc.bold("Exemplos:")}
|
|
135
144
|
${pc.dim("$")} nimbus create my-landing --landing
|
|
136
145
|
${pc.dim("$")} nimbus create my-app --app
|
|
137
146
|
${pc.dim("$")} nimbus analyze ./my-project
|
|
138
147
|
${pc.dim("$")} nimbus upgrade --plan
|
|
148
|
+
${pc.dim("$")} nimbus update
|
|
139
149
|
${pc.dim("$")} nimbus lola install
|
|
140
|
-
${pc.dim("$")} nimbus lola suggest "add support for X"
|
|
141
150
|
`)
|
|
142
151
|
}
|
|
143
152
|
|