@nimbuslab/cli 0.14.0 → 0.16.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 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.14.0",
153
+ version: "0.16.0",
154
154
  description: "CLI para criar projetos nimbuslab",
155
155
  type: "module",
156
156
  bin: {
@@ -2382,84 +2382,149 @@ async function getLatestVersion() {
2382
2382
  return null;
2383
2383
  }
2384
2384
  }
2385
+ function detectPackageManager2() {
2386
+ try {
2387
+ const bunResult = spawnSync("bun", ["pm", "ls", "-g"], {
2388
+ encoding: "utf-8",
2389
+ shell: true,
2390
+ timeout: 5000
2391
+ });
2392
+ if (bunResult.stdout && bunResult.stdout.includes(PACKAGE_NAME)) {
2393
+ return "bun";
2394
+ }
2395
+ } catch {}
2396
+ try {
2397
+ const npmResult = spawnSync("npm", ["ls", "-g", PACKAGE_NAME, "--json"], {
2398
+ encoding: "utf-8",
2399
+ shell: true,
2400
+ timeout: 5000
2401
+ });
2402
+ if (npmResult.stdout) {
2403
+ const data = JSON.parse(npmResult.stdout);
2404
+ if (data.dependencies?.[PACKAGE_NAME]) {
2405
+ return "npm";
2406
+ }
2407
+ }
2408
+ } catch {}
2409
+ return "unknown";
2410
+ }
2385
2411
  function getCurrentVersion() {
2412
+ try {
2413
+ const bunResult = spawnSync("bun", ["pm", "ls", "-g"], {
2414
+ encoding: "utf-8",
2415
+ shell: true,
2416
+ timeout: 5000
2417
+ });
2418
+ if (bunResult.stdout) {
2419
+ const match = bunResult.stdout.match(new RegExp(`${PACKAGE_NAME.replace("/", "\\/")}@([\\d.]+)`));
2420
+ if (match?.[1]) {
2421
+ return match[1];
2422
+ }
2423
+ }
2424
+ } catch {}
2386
2425
  try {
2387
2426
  const result = spawnSync("npm", ["ls", "-g", PACKAGE_NAME, "--json"], {
2388
2427
  encoding: "utf-8",
2389
- shell: true
2428
+ shell: true,
2429
+ timeout: 5000
2390
2430
  });
2391
2431
  if (result.stdout) {
2392
2432
  const data = JSON.parse(result.stdout);
2393
- return data.dependencies?.[PACKAGE_NAME]?.version || "unknown";
2433
+ if (data.dependencies?.[PACKAGE_NAME]?.version) {
2434
+ return data.dependencies[PACKAGE_NAME].version;
2435
+ }
2394
2436
  }
2395
2437
  } catch {}
2396
2438
  return "unknown";
2397
2439
  }
2398
2440
  async function update(args) {
2399
- const flag = args[0];
2441
+ const forceFlag = args.includes("--force") || args.includes("-f");
2442
+ const filteredArgs = args.filter((a) => a !== "--force" && a !== "-f");
2443
+ const flag = filteredArgs[0];
2400
2444
  if (flag === "--list" || flag === "-l") {
2401
- Ie(import_picocolors6.default.cyan("Vers\xF5es dispon\xEDveis"));
2445
+ Ie(import_picocolors6.default.cyan("Versoes disponiveis"));
2402
2446
  const spinner2 = Y2();
2403
- spinner2.start("Buscando vers\xF5es...");
2447
+ spinner2.start("Buscando versoes...");
2404
2448
  const versions = await getAvailableVersions();
2405
- spinner2.stop("Vers\xF5es encontradas");
2449
+ spinner2.stop("Versoes encontradas");
2406
2450
  if (versions.length === 0) {
2407
- M2.error("N\xE3o foi poss\xEDvel buscar as vers\xF5es");
2451
+ M2.error("Nao foi possivel buscar as versoes");
2408
2452
  return;
2409
2453
  }
2410
2454
  const current = getCurrentVersion();
2455
+ const pm2 = detectPackageManager2();
2411
2456
  console.log();
2412
- console.log(import_picocolors6.default.bold("\xDAltimas 10 vers\xF5es:"));
2457
+ console.log(import_picocolors6.default.bold("Ultimas 10 versoes:"));
2413
2458
  versions.slice(0, 10).forEach((v2, i) => {
2414
2459
  const isCurrent = v2 === current;
2415
- const prefix = isCurrent ? import_picocolors6.default.green("\u2192 ") : " ";
2460
+ const prefix = isCurrent ? import_picocolors6.default.green("-> ") : " ";
2416
2461
  const suffix = isCurrent ? import_picocolors6.default.dim(" (instalada)") : "";
2417
2462
  const isLatest = i === 0 ? import_picocolors6.default.yellow(" (latest)") : "";
2418
2463
  console.log(`${prefix}${v2}${suffix}${isLatest}`);
2419
2464
  });
2420
2465
  console.log();
2421
- console.log(import_picocolors6.default.dim(`Total: ${versions.length} vers\xF5es`));
2422
- console.log(import_picocolors6.default.dim(`Instalar vers\xE3o espec\xEDfica: nimbus update <vers\xE3o>`));
2466
+ console.log(import_picocolors6.default.dim(`Total: ${versions.length} versoes`));
2467
+ console.log(import_picocolors6.default.dim(`Package manager detectado: ${pm2 === "unknown" ? "nenhum" : pm2}`));
2468
+ console.log(import_picocolors6.default.dim(`Instalar versao especifica: nimbus update <versao>`));
2469
+ console.log(import_picocolors6.default.dim(`Forcar reinstalacao: nimbus update --force`));
2423
2470
  return;
2424
2471
  }
2425
2472
  const targetVersion = flag || "latest";
2426
- const isSpecificVersion = flag && flag !== "latest";
2473
+ const isSpecificVersion = flag && flag !== "latest" && !flag.startsWith("-");
2427
2474
  Ie(import_picocolors6.default.cyan(`Atualizando ${PACKAGE_NAME}`));
2428
2475
  const spinner = Y2();
2429
- spinner.start("Verificando vers\xE3o atual...");
2476
+ spinner.start("Detectando package manager...");
2477
+ const detectedPm = detectPackageManager2();
2478
+ const pm = detectedPm === "unknown" ? "bun" : detectedPm;
2479
+ spinner.stop(`Package manager: ${pm}${detectedPm === "unknown" ? " (padrao)" : ""}`);
2480
+ spinner.start("Verificando versao atual...");
2430
2481
  const currentVersion = getCurrentVersion();
2431
- spinner.stop(`Vers\xE3o atual: ${currentVersion}`);
2482
+ spinner.stop(`Versao atual: ${currentVersion === "unknown" ? "nao instalado" : currentVersion}`);
2483
+ let latestVersion = null;
2432
2484
  if (!isSpecificVersion) {
2433
- spinner.start("Verificando \xFAltima vers\xE3o...");
2434
- const latest = await getLatestVersion();
2435
- spinner.stop(`\xDAltima vers\xE3o: ${latest || "desconhecida"}`);
2436
- if (latest && latest === currentVersion) {
2437
- M2.success("Voc\xEA j\xE1 est\xE1 na \xFAltima vers\xE3o!");
2485
+ spinner.start("Verificando ultima versao no npm...");
2486
+ latestVersion = await getLatestVersion();
2487
+ spinner.stop(`Ultima versao: ${latestVersion || "desconhecida"}`);
2488
+ if (!forceFlag && latestVersion && latestVersion === currentVersion) {
2489
+ M2.success("Voce ja esta na ultima versao!");
2490
+ console.log(import_picocolors6.default.dim(" Use --force para reinstalar"));
2438
2491
  return;
2439
2492
  }
2440
2493
  }
2441
- const versionText = isSpecificVersion ? targetVersion : "latest";
2494
+ const versionText = isSpecificVersion ? targetVersion : latestVersion || "latest";
2495
+ const actionText = forceFlag ? "Reinstalar" : "Atualizar";
2442
2496
  const confirmUpdate = await ye({
2443
- message: `Atualizar para ${versionText}?`,
2497
+ message: `${actionText} para ${versionText} usando ${pm}?`,
2444
2498
  initialValue: true
2445
2499
  });
2446
2500
  if (pD(confirmUpdate) || !confirmUpdate) {
2447
- xe("Atualiza\xE7\xE3o cancelada");
2501
+ xe("Atualizacao cancelada");
2448
2502
  return;
2449
2503
  }
2450
2504
  spinner.start("Atualizando...");
2451
2505
  try {
2452
- const packageSpec = isSpecificVersion ? `${PACKAGE_NAME}@${targetVersion}` : PACKAGE_NAME;
2453
- execSync(`npm install -g ${packageSpec}`, {
2454
- stdio: "pipe",
2455
- encoding: "utf-8"
2456
- });
2457
- spinner.stop("Atualiza\xE7\xE3o conclu\xEDda!");
2506
+ const packageSpec = isSpecificVersion ? `${PACKAGE_NAME}@${targetVersion}` : latestVersion ? `${PACKAGE_NAME}@${latestVersion}` : PACKAGE_NAME;
2507
+ if (pm === "bun") {
2508
+ if (forceFlag) {
2509
+ try {
2510
+ execSync(`bun remove -g ${PACKAGE_NAME}`, { stdio: "pipe", encoding: "utf-8" });
2511
+ } catch {}
2512
+ }
2513
+ execSync(`bun add -g ${packageSpec}`, { stdio: "pipe", encoding: "utf-8" });
2514
+ } else {
2515
+ const forceArg = forceFlag ? " --force" : "";
2516
+ execSync(`npm install -g ${packageSpec}${forceArg}`, { stdio: "pipe", encoding: "utf-8" });
2517
+ }
2518
+ spinner.stop("Atualizacao concluida!");
2458
2519
  const newVersion = getCurrentVersion();
2459
- M2.success(`${PACKAGE_NAME} atualizado: ${currentVersion} \u2192 ${newVersion}`);
2520
+ if (currentVersion === newVersion && !forceFlag) {
2521
+ M2.warn("Versao nao mudou. Tente com --force");
2522
+ } else {
2523
+ M2.success(`${PACKAGE_NAME} atualizado: ${currentVersion} -> ${newVersion}`);
2524
+ }
2460
2525
  Se(import_picocolors6.default.green("Pronto!"));
2461
2526
  } catch (error) {
2462
- spinner.stop("Erro na atualiza\xE7\xE3o");
2527
+ spinner.stop("Erro na atualizacao");
2463
2528
  const err = error;
2464
2529
  M2.error("Falha ao atualizar");
2465
2530
  if (err.stderr) {
@@ -2467,7 +2532,11 @@ async function update(args) {
2467
2532
  }
2468
2533
  console.log();
2469
2534
  console.log(import_picocolors6.default.yellow("Tente manualmente:"));
2470
- console.log(import_picocolors6.default.cyan(` npm install -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
2535
+ if (pm === "bun") {
2536
+ console.log(import_picocolors6.default.cyan(` bun add -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
2537
+ } else {
2538
+ console.log(import_picocolors6.default.cyan(` npm install -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
2539
+ }
2471
2540
  }
2472
2541
  }
2473
2542
 
@@ -2482,6 +2551,16 @@ var LOLA_REPO = "git@github.com:nimbuslab/lola.git";
2482
2551
  var USER_MEMORY = join3(HOME, ".claude", "USER_MEMORY.md");
2483
2552
  var LOLA_MEMORY_URL = "https://lola.nimbuslab.com.br/sse";
2484
2553
  var LOLA_MEMORY_NAME = "lola-memory";
2554
+ var GEMINI_DIR = join3(HOME, ".gemini");
2555
+ var GEMINI_SETTINGS = join3(GEMINI_DIR, "GEMINI.md");
2556
+ function hasClaudeCLI() {
2557
+ const result = Bun.spawnSync(["which", "claude"], { stdout: "pipe" });
2558
+ return result.exitCode === 0;
2559
+ }
2560
+ function hasGeminiCLI() {
2561
+ const result = Bun.spawnSync(["which", "gemini"], { stdout: "pipe" });
2562
+ return result.exitCode === 0;
2563
+ }
2485
2564
  async function installLolaMemoryMCP() {
2486
2565
  console.log();
2487
2566
  console.log(import_picocolors7.default.cyan(" Configurando lola-memory MCP..."));
@@ -2527,185 +2606,147 @@ async function installLolaMemoryMCP() {
2527
2606
  console.log(import_picocolors7.default.dim(' learn "content" - Salvar conhecimento'));
2528
2607
  console.log(import_picocolors7.default.dim(" memory_stats - Ver estatisticas"));
2529
2608
  }
2530
- async function installLola() {
2609
+ async function installGeminiCLI() {
2531
2610
  console.log();
2532
- console.log(import_picocolors7.default.cyan(" Lola - Code Agent da nimbuslab"));
2533
- console.log(import_picocolors7.default.dim(" ==============================="));
2611
+ console.log(import_picocolors7.default.cyan(" Instalando Gemini CLI..."));
2612
+ const result = Bun.spawnSync(["npm", "install", "-g", "@google/gemini-cli"], {
2613
+ stdout: "inherit",
2614
+ stderr: "inherit"
2615
+ });
2616
+ if (result.exitCode !== 0) {
2617
+ console.log(import_picocolors7.default.red(" Erro ao instalar Gemini CLI"));
2618
+ console.log(import_picocolors7.default.dim(" Tente manualmente: npm install -g @google/gemini-cli"));
2619
+ return false;
2620
+ }
2621
+ console.log(import_picocolors7.default.green(" Gemini CLI instalado!"));
2622
+ return true;
2623
+ }
2624
+ async function installGeminiMCP() {
2534
2625
  console.log();
2535
- const isUpdate = existsSync2(LOLA_DIR);
2536
- if (isUpdate) {
2537
- console.log(import_picocolors7.default.dim(` Lola ja instalada em ${LOLA_DIR}`));
2538
- console.log(import_picocolors7.default.cyan(" Atualizando..."));
2539
- const result = Bun.spawnSync(["git", "pull", "--quiet"], {
2540
- cwd: LOLA_DIR,
2541
- stdout: "inherit",
2542
- stderr: "inherit"
2543
- });
2544
- if (result.exitCode !== 0) {
2545
- console.log(import_picocolors7.default.red(" Erro ao atualizar Lola"));
2546
- process.exit(1);
2547
- }
2548
- console.log(import_picocolors7.default.green(" Atualizado!"));
2549
- } else {
2550
- console.log(import_picocolors7.default.cyan(` Instalando Lola em ${LOLA_DIR}...`));
2551
- const result = Bun.spawnSync(["git", "clone", "--quiet", LOLA_REPO, LOLA_DIR], {
2552
- stdout: "inherit",
2553
- stderr: "inherit"
2554
- });
2555
- if (result.exitCode !== 0) {
2556
- console.log(import_picocolors7.default.red(" Erro ao clonar repositorio"));
2557
- console.log(import_picocolors7.default.dim(" Verifique se tem acesso ao repo nimbuslab/lola"));
2558
- process.exit(1);
2559
- }
2560
- console.log(import_picocolors7.default.green(" Instalado!"));
2626
+ console.log(import_picocolors7.default.cyan(" Configurando MCP no Gemini..."));
2627
+ const settingsPath = join3(GEMINI_DIR, "settings.json");
2628
+ if (!existsSync2(GEMINI_DIR)) {
2629
+ await Bun.$`mkdir -p ${GEMINI_DIR}`;
2630
+ }
2631
+ let settings = {};
2632
+ if (existsSync2(settingsPath)) {
2633
+ try {
2634
+ const content = await Bun.file(settingsPath).text();
2635
+ settings = JSON.parse(content);
2636
+ } catch {}
2637
+ }
2638
+ const mcpServers = settings.mcpServers || {};
2639
+ if (mcpServers[LOLA_MEMORY_NAME]) {
2640
+ console.log(import_picocolors7.default.green(" MCP lola-memory ja configurado no Gemini"));
2641
+ return;
2642
+ }
2643
+ mcpServers[LOLA_MEMORY_NAME] = {
2644
+ url: LOLA_MEMORY_URL
2645
+ };
2646
+ settings.mcpServers = mcpServers;
2647
+ await Bun.write(settingsPath, JSON.stringify(settings, null, 2));
2648
+ console.log(import_picocolors7.default.green(" MCP lola-memory adicionado ao Gemini!"));
2649
+ }
2650
+ async function installGeminiSystemPrompt() {
2651
+ console.log();
2652
+ console.log(import_picocolors7.default.cyan(" Configurando GEMINI.md..."));
2653
+ if (!existsSync2(GEMINI_DIR)) {
2654
+ await Bun.$`mkdir -p ${GEMINI_DIR}`;
2561
2655
  }
2562
- const isWindows = process.platform === "win32";
2563
2656
  const lolaAgent = join3(LOLA_DIR, "agents", "claude.md");
2657
+ if (!existsSync2(lolaAgent)) {
2658
+ console.log(import_picocolors7.default.yellow(" Agent Lola nao encontrado"));
2659
+ console.log(import_picocolors7.default.dim(" Rode 'nimbus lola install' primeiro"));
2660
+ return;
2661
+ }
2662
+ let content = await Bun.file(lolaAgent).text();
2663
+ content = content.replace(/^---[\s\S]*?---\n/, "");
2664
+ content = content.replace(/Claude Code/g, "Gemini CLI");
2665
+ content = content.replace(/Claude CLI/g, "Gemini CLI");
2666
+ const geminiContent = `# Lola - Code Agent (Gemini)
2667
+
2668
+ > Este arquivo configura a Lola para o Gemini CLI
2669
+ > Gerado automaticamente por: nimbus lola install
2670
+
2671
+ ---
2672
+
2673
+ ${content}`;
2674
+ await Bun.write(GEMINI_SETTINGS, geminiContent);
2675
+ console.log(import_picocolors7.default.green(" GEMINI.md criado!"));
2676
+ }
2677
+ async function createGeminiCommand() {
2678
+ const isWindows = process.platform === "win32";
2679
+ const lolaAgent = GEMINI_SETTINGS;
2564
2680
  console.log();
2565
- console.log(import_picocolors7.default.cyan(" Configurando comando lola..."));
2681
+ console.log(import_picocolors7.default.cyan(" Configurando comando lola-gemini..."));
2566
2682
  if (isWindows) {
2567
- const ps5ProfileDir = join3(HOME, "Documents", "WindowsPowerShell");
2568
2683
  const ps7ProfileDir = join3(HOME, "Documents", "PowerShell");
2569
2684
  const profileName = "Microsoft.PowerShell_profile.ps1";
2570
- const lolaFunction = `
2571
- # Lola - Code Agent da nimbuslab
2572
- function lola {
2685
+ const profilePath = join3(ps7ProfileDir, profileName);
2686
+ const lolaGeminiFunction = `
2687
+ # Lola (Gemini) - Code Agent da nimbuslab
2688
+ function lola-gemini {
2573
2689
  param([Parameter(ValueFromRemainingArguments=$true)]$args)
2574
- $agent = "$env:USERPROFILE\\.lola\\agents\\claude.md"
2575
- if (Test-Path $agent) {
2576
- claude --append-system-prompt-file $agent @args
2577
- } else {
2578
- Write-Host "Agente Lola nao encontrado. Rode: nimbus lola install"
2579
- }
2690
+ gemini @args
2580
2691
  }
2581
2692
  `;
2582
- const profiles = [
2583
- { dir: ps5ProfileDir, name: "PowerShell 5.x" },
2584
- { dir: ps7ProfileDir, name: "PowerShell 7+" }
2585
- ];
2586
- let addedToAny = false;
2587
- for (const { dir, name } of profiles) {
2588
- const profilePath = join3(dir, profileName);
2589
- if (!existsSync2(dir)) {
2590
- await Bun.$`mkdir -p ${dir}`;
2591
- }
2592
- let profileContent = "";
2593
- if (existsSync2(profilePath)) {
2594
- profileContent = await Bun.file(profilePath).text();
2595
- }
2596
- if (!profileContent.includes("function lola")) {
2597
- await Bun.write(profilePath, profileContent + lolaFunction);
2598
- console.log(import_picocolors7.default.green(` Funcao lola adicionada ao ${name} profile`));
2599
- addedToAny = true;
2600
- }
2693
+ if (!existsSync2(ps7ProfileDir)) {
2694
+ await Bun.$`mkdir -p ${ps7ProfileDir}`;
2601
2695
  }
2602
- if (addedToAny) {
2603
- console.log(import_picocolors7.default.yellow(" Reinicie o PowerShell para usar o comando 'lola'"));
2604
- console.log();
2605
- console.log(import_picocolors7.default.yellow(" IMPORTANTE (Windows):"));
2606
- console.log(import_picocolors7.default.dim(" Se o comando 'lola' nao funcionar, execute primeiro:"));
2607
- console.log(import_picocolors7.default.cyan(" Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser"));
2608
- console.log(import_picocolors7.default.dim(" Isso habilita execucao de scripts no PowerShell."));
2696
+ let profileContent = "";
2697
+ if (existsSync2(profilePath)) {
2698
+ profileContent = await Bun.file(profilePath).text();
2699
+ }
2700
+ if (!profileContent.includes("function lola-gemini")) {
2701
+ await Bun.write(profilePath, profileContent + lolaGeminiFunction);
2702
+ console.log(import_picocolors7.default.green(" Funcao lola-gemini adicionada ao PowerShell"));
2609
2703
  } else {
2610
- console.log(import_picocolors7.default.green(" Funcao lola ja existe nos profiles do PowerShell"));
2704
+ console.log(import_picocolors7.default.green(" Funcao lola-gemini ja existe"));
2611
2705
  }
2612
2706
  } else {
2613
2707
  const binDir = join3(HOME, ".local", "bin");
2614
- const lolaScript = join3(binDir, "lola");
2615
- if (!existsSync2(lolaScript)) {
2708
+ const lolaGeminiScript = join3(binDir, "lola-gemini");
2709
+ if (!existsSync2(lolaGeminiScript)) {
2616
2710
  await Bun.$`mkdir -p ${binDir}`;
2617
2711
  const unixScript = `#!/bin/bash
2618
- # lola - Code Agent da nimbuslab
2619
- LOLA_AGENT="${lolaAgent}"
2712
+ # lola-gemini - Code Agent da nimbuslab (Gemini)
2620
2713
 
2621
2714
  if [[ "$1" == "-h" || "$1" == "--help" ]]; then
2622
- echo "lola - Code Agent da nimbuslab"
2623
- echo "Uso: lola [args]"
2624
- echo " lola Abre Claude CLI com a Lola"
2625
- echo " lola --resume Resume sessao anterior"
2715
+ echo "lola-gemini - Code Agent da nimbuslab (Gemini)"
2716
+ echo "Uso: lola-gemini [args]"
2717
+ echo " lola-gemini Abre Gemini CLI com a Lola"
2626
2718
  exit 0
2627
2719
  fi
2628
2720
 
2629
- if [[ -f "$LOLA_AGENT" ]]; then
2630
- exec claude --append-system-prompt-file "$LOLA_AGENT" "$@"
2631
- else
2632
- echo "Agente Lola nao encontrado: $LOLA_AGENT"
2633
- echo "Rode: nimbus lola install"
2634
- exit 1
2635
- fi
2721
+ exec gemini "$@"
2636
2722
  `;
2637
- await Bun.write(lolaScript, unixScript);
2638
- await Bun.$`chmod +x ${lolaScript}`;
2639
- console.log(import_picocolors7.default.green(` Script lola criado em ${lolaScript}`));
2640
- const pathEnv = process.env.PATH || "";
2641
- if (!pathEnv.includes(".local/bin")) {
2642
- console.log();
2643
- console.log(import_picocolors7.default.yellow(" IMPORTANTE: Adicione ~/.local/bin ao seu PATH"));
2644
- console.log(import_picocolors7.default.dim(" Adicione ao seu ~/.bashrc ou ~/.zshrc:"));
2645
- console.log(import_picocolors7.default.dim(' export PATH="$HOME/.local/bin:$PATH"'));
2646
- }
2723
+ await Bun.write(lolaGeminiScript, unixScript);
2724
+ await Bun.$`chmod +x ${lolaGeminiScript}`;
2725
+ console.log(import_picocolors7.default.green(` Script lola-gemini criado em ${lolaGeminiScript}`));
2647
2726
  } else {
2648
- console.log(import_picocolors7.default.green(" Script lola ja existe"));
2727
+ console.log(import_picocolors7.default.green(" Script lola-gemini ja existe"));
2649
2728
  }
2650
2729
  }
2651
- await installLolaMemoryMCP();
2652
- const claudeDir = join3(HOME, ".claude");
2653
- if (!existsSync2(USER_MEMORY)) {
2654
- console.log();
2655
- console.log(import_picocolors7.default.cyan(" Configurando USER_MEMORY.md..."));
2656
- const gitUserResult = Bun.spawnSync(["git", "config", "user.name"], { stdout: "pipe" });
2657
- const gitEmailResult = Bun.spawnSync(["git", "config", "user.email"], { stdout: "pipe" });
2658
- const gitUser = gitUserResult.stdout.toString().trim() || "Dev";
2659
- const gitEmail = gitEmailResult.stdout.toString().trim() || "";
2660
- const hostname = process.env.HOSTNAME || process.env.COMPUTERNAME || "local";
2661
- const today = new Date().toISOString().split("T")[0];
2662
- await Bun.$`mkdir -p ${claudeDir}`;
2663
- const content = `# User Memory
2664
-
2665
- Memoria persistente para sessoes Claude Code
2666
-
2667
- ---
2668
-
2669
- ## Dev
2670
-
2671
- **Nome:** ${gitUser}
2672
- **Email:** ${gitEmail}
2673
- **Maquina:** ${hostname}
2674
- **Instalacao:** ${today}
2675
-
2676
- ---
2677
-
2678
- ## Configuracoes da Lola
2679
-
2680
- \`\`\`
2681
- lola_profile: millennial
2682
- \`\`\`
2683
-
2684
- ---
2685
-
2686
- ## Ultima Sessao
2687
-
2688
- (sera preenchido automaticamente)
2689
-
2690
- ---
2691
- `;
2692
- await Bun.write(USER_MEMORY, content);
2693
- console.log(import_picocolors7.default.green(` USER_MEMORY.md criado para ${gitUser}!`));
2730
+ }
2731
+ async function setupGemini() {
2732
+ if (!hasGeminiCLI()) {
2733
+ const installed = await installGeminiCLI();
2734
+ if (!installed)
2735
+ return;
2736
+ } else {
2737
+ console.log(import_picocolors7.default.green(" Gemini CLI ja instalado"));
2694
2738
  }
2739
+ await installGeminiMCP();
2740
+ await installGeminiSystemPrompt();
2741
+ await createGeminiCommand();
2695
2742
  console.log();
2696
- console.log(import_picocolors7.default.green(" Instalacao concluida!"));
2697
- console.log();
2698
- console.log(import_picocolors7.default.bold(" Para usar a Lola:"));
2699
- console.log(import_picocolors7.default.dim(" lola ") + import_picocolors7.default.white("# Iniciar sessao"));
2700
- console.log();
2701
- console.log(import_picocolors7.default.bold(" lola-memory (conhecimento compartilhado):"));
2702
- console.log(import_picocolors7.default.dim(' remember "query" ') + import_picocolors7.default.white("# Buscar conhecimento"));
2703
- console.log(import_picocolors7.default.dim(' learn "content" ') + import_picocolors7.default.white("# Salvar conhecimento"));
2704
- console.log(import_picocolors7.default.dim(" memory_stats ") + import_picocolors7.default.white("# Ver estatisticas"));
2743
+ console.log(import_picocolors7.default.green(" Gemini configurado!"));
2705
2744
  console.log();
2706
- console.log(import_picocolors7.default.bold(" Para mudar perfil, edite ~/.claude/USER_MEMORY.md:"));
2707
- console.log(import_picocolors7.default.dim(" lola_profile: millennial|genz|profissional|nerd|chill"));
2745
+ console.log(import_picocolors7.default.bold(" Para usar:"));
2746
+ console.log(import_picocolors7.default.dim(" lola-gemini ") + import_picocolors7.default.white("# Iniciar sessao com Gemini"));
2747
+ console.log(import_picocolors7.default.dim(" gemini ") + import_picocolors7.default.white("# Gemini puro (sem Lola)"));
2708
2748
  console.log();
2749
+ console.log(import_picocolors7.default.dim(" Na primeira execucao, faca login com sua conta Google."));
2709
2750
  }
2710
2751
  async function suggestImprovement(message) {
2711
2752
  if (!message) {
@@ -2807,7 +2848,7 @@ async function onboardDev() {
2807
2848
  if (!existsSync2(LOLA_DIR)) {
2808
2849
  console.log(import_picocolors7.default.yellow(" Lola nao instalada. Instalando primeiro..."));
2809
2850
  console.log();
2810
- await installLola();
2851
+ await installLolaBase();
2811
2852
  console.log();
2812
2853
  }
2813
2854
  const gitUser = Bun.spawnSync(["git", "config", "user.name"], { stdout: "pipe" });
@@ -3027,10 +3068,267 @@ async function runQuiz() {
3027
3068
  }
3028
3069
  console.log();
3029
3070
  }
3071
+ async function installInteractive() {
3072
+ console.log();
3073
+ console.log(import_picocolors7.default.cyan(" Lola - Code Agent da nimbuslab"));
3074
+ console.log(import_picocolors7.default.dim(" ==============================="));
3075
+ console.log();
3076
+ const hasClaude = hasClaudeCLI();
3077
+ const hasGemini = hasGeminiCLI();
3078
+ console.log(import_picocolors7.default.dim(" Detectando agents..."));
3079
+ console.log(import_picocolors7.default.dim(` Claude CLI: ${hasClaude ? import_picocolors7.default.green("instalado") : import_picocolors7.default.yellow("nao encontrado")}`));
3080
+ console.log(import_picocolors7.default.dim(` Gemini CLI: ${hasGemini ? import_picocolors7.default.green("instalado") : import_picocolors7.default.yellow("nao encontrado")}`));
3081
+ console.log();
3082
+ const agentChoice = await ve({
3083
+ message: "Qual agent deseja configurar?",
3084
+ options: [
3085
+ {
3086
+ value: "all",
3087
+ label: "Todos (Recomendado)",
3088
+ hint: "Configura Claude e Gemini"
3089
+ },
3090
+ {
3091
+ value: "claude",
3092
+ label: "Apenas Claude",
3093
+ hint: hasClaude ? "Ja instalado" : "Sera instalado"
3094
+ },
3095
+ {
3096
+ value: "gemini",
3097
+ label: "Apenas Gemini",
3098
+ hint: hasGemini ? "Ja instalado" : "Sera instalado"
3099
+ }
3100
+ ]
3101
+ });
3102
+ if (pD(agentChoice)) {
3103
+ xe("Instalacao cancelada");
3104
+ process.exit(0);
3105
+ }
3106
+ const choice = agentChoice;
3107
+ await installLolaBase();
3108
+ if (choice === "claude" || choice === "all") {
3109
+ console.log();
3110
+ console.log(import_picocolors7.default.bgBlue(import_picocolors7.default.white(" CLAUDE ")));
3111
+ await setupClaude();
3112
+ }
3113
+ if (choice === "gemini" || choice === "all") {
3114
+ console.log();
3115
+ console.log(import_picocolors7.default.bgMagenta(import_picocolors7.default.white(" GEMINI ")));
3116
+ await setupGemini();
3117
+ }
3118
+ console.log();
3119
+ console.log(import_picocolors7.default.green(" ==============================="));
3120
+ console.log(import_picocolors7.default.green(" Instalacao concluida!"));
3121
+ console.log(import_picocolors7.default.green(" ==============================="));
3122
+ console.log();
3123
+ if (choice === "claude" || choice === "all") {
3124
+ console.log(import_picocolors7.default.dim(" lola ") + import_picocolors7.default.white("# Claude com Lola"));
3125
+ }
3126
+ if (choice === "gemini" || choice === "all") {
3127
+ console.log(import_picocolors7.default.dim(" lola-gemini ") + import_picocolors7.default.white("# Gemini com Lola"));
3128
+ }
3129
+ console.log();
3130
+ console.log(import_picocolors7.default.bold(" lola-memory (compartilhado entre agents):"));
3131
+ console.log(import_picocolors7.default.dim(" remember, learn, memory_stats"));
3132
+ console.log();
3133
+ }
3134
+ async function installLolaBase() {
3135
+ console.log();
3136
+ console.log(import_picocolors7.default.cyan(" Instalando base Lola (~/.lola)..."));
3137
+ const isUpdate = existsSync2(LOLA_DIR);
3138
+ if (isUpdate) {
3139
+ console.log(import_picocolors7.default.dim(` Lola ja instalada em ${LOLA_DIR}`));
3140
+ console.log(import_picocolors7.default.dim(" Atualizando..."));
3141
+ const statusCheck = Bun.spawnSync(["git", "status", "--porcelain"], {
3142
+ cwd: LOLA_DIR,
3143
+ stdout: "pipe"
3144
+ });
3145
+ const hasLocalChanges = statusCheck.stdout.toString().trim().length > 0;
3146
+ if (hasLocalChanges) {
3147
+ console.log(import_picocolors7.default.dim(" Salvando mudancas locais..."));
3148
+ Bun.spawnSync(["git", "stash", "--quiet"], {
3149
+ cwd: LOLA_DIR,
3150
+ stdout: "pipe",
3151
+ stderr: "pipe"
3152
+ });
3153
+ }
3154
+ const result = Bun.spawnSync(["git", "pull", "--quiet"], {
3155
+ cwd: LOLA_DIR,
3156
+ stdout: "inherit",
3157
+ stderr: "inherit"
3158
+ });
3159
+ if (hasLocalChanges) {
3160
+ console.log(import_picocolors7.default.dim(" Restaurando mudancas locais..."));
3161
+ const stashPop = Bun.spawnSync(["git", "stash", "pop", "--quiet"], {
3162
+ cwd: LOLA_DIR,
3163
+ stdout: "pipe",
3164
+ stderr: "pipe"
3165
+ });
3166
+ if (stashPop.exitCode !== 0) {
3167
+ console.log(import_picocolors7.default.yellow(" Aviso: conflito ao restaurar mudancas locais"));
3168
+ console.log(import_picocolors7.default.dim(" Verifique ~/.lola e resolva manualmente: git stash pop"));
3169
+ }
3170
+ }
3171
+ if (result.exitCode !== 0) {
3172
+ console.log(import_picocolors7.default.red(" Erro ao atualizar Lola"));
3173
+ process.exit(1);
3174
+ }
3175
+ console.log(import_picocolors7.default.green(" Atualizado!"));
3176
+ } else {
3177
+ console.log(import_picocolors7.default.dim(` Clonando em ${LOLA_DIR}...`));
3178
+ const result = Bun.spawnSync(["git", "clone", "--quiet", LOLA_REPO, LOLA_DIR], {
3179
+ stdout: "inherit",
3180
+ stderr: "inherit"
3181
+ });
3182
+ if (result.exitCode !== 0) {
3183
+ console.log(import_picocolors7.default.red(" Erro ao clonar repositorio"));
3184
+ console.log(import_picocolors7.default.dim(" Verifique se tem acesso ao repo nimbuslab/lola"));
3185
+ process.exit(1);
3186
+ }
3187
+ console.log(import_picocolors7.default.green(" Instalado!"));
3188
+ }
3189
+ }
3190
+ async function setupClaude() {
3191
+ if (!hasClaudeCLI()) {
3192
+ console.log(import_picocolors7.default.yellow(" Claude CLI nao encontrado"));
3193
+ console.log(import_picocolors7.default.dim(" Instale: https://claude.ai/download"));
3194
+ console.log(import_picocolors7.default.dim(" Depois rode 'nimbus lola install' novamente"));
3195
+ return;
3196
+ }
3197
+ console.log(import_picocolors7.default.green(" Claude CLI encontrado"));
3198
+ const isWindows = process.platform === "win32";
3199
+ const lolaAgent = join3(LOLA_DIR, "agents", "claude.md");
3200
+ console.log();
3201
+ console.log(import_picocolors7.default.cyan(" Configurando comando lola..."));
3202
+ if (isWindows) {
3203
+ const ps5ProfileDir = join3(HOME, "Documents", "WindowsPowerShell");
3204
+ const ps7ProfileDir = join3(HOME, "Documents", "PowerShell");
3205
+ const profileName = "Microsoft.PowerShell_profile.ps1";
3206
+ const lolaFunction = `
3207
+ # Lola - Code Agent da nimbuslab
3208
+ function lola {
3209
+ param([Parameter(ValueFromRemainingArguments=$true)]$args)
3210
+ $agent = "$env:USERPROFILE\\.lola\\agents\\claude.md"
3211
+ if (Test-Path $agent) {
3212
+ claude --append-system-prompt-file $agent @args
3213
+ } else {
3214
+ Write-Host "Agente Lola nao encontrado. Rode: nimbus lola install"
3215
+ }
3216
+ }
3217
+ `;
3218
+ const profiles = [
3219
+ { dir: ps5ProfileDir, name: "PowerShell 5.x" },
3220
+ { dir: ps7ProfileDir, name: "PowerShell 7+" }
3221
+ ];
3222
+ let addedToAny = false;
3223
+ for (const { dir, name } of profiles) {
3224
+ const profilePath = join3(dir, profileName);
3225
+ if (!existsSync2(dir)) {
3226
+ await Bun.$`mkdir -p ${dir}`;
3227
+ }
3228
+ let profileContent = "";
3229
+ if (existsSync2(profilePath)) {
3230
+ profileContent = await Bun.file(profilePath).text();
3231
+ }
3232
+ if (!profileContent.includes("function lola")) {
3233
+ await Bun.write(profilePath, profileContent + lolaFunction);
3234
+ console.log(import_picocolors7.default.green(` Funcao lola adicionada ao ${name} profile`));
3235
+ addedToAny = true;
3236
+ }
3237
+ }
3238
+ if (addedToAny) {
3239
+ console.log(import_picocolors7.default.yellow(" Reinicie o PowerShell para usar o comando 'lola'"));
3240
+ } else {
3241
+ console.log(import_picocolors7.default.green(" Funcao lola ja existe"));
3242
+ }
3243
+ } else {
3244
+ const binDir = join3(HOME, ".local", "bin");
3245
+ const lolaScript = join3(binDir, "lola");
3246
+ if (!existsSync2(lolaScript)) {
3247
+ await Bun.$`mkdir -p ${binDir}`;
3248
+ const unixScript = `#!/bin/bash
3249
+ # lola - Code Agent da nimbuslab
3250
+ LOLA_AGENT="${lolaAgent}"
3251
+
3252
+ if [[ "$1" == "-h" || "$1" == "--help" ]]; then
3253
+ echo "lola - Code Agent da nimbuslab"
3254
+ echo "Uso: lola [args]"
3255
+ echo " lola Abre Claude CLI com a Lola"
3256
+ echo " lola --resume Resume sessao anterior"
3257
+ exit 0
3258
+ fi
3259
+
3260
+ if [[ -f "$LOLA_AGENT" ]]; then
3261
+ exec claude --append-system-prompt-file "$LOLA_AGENT" "$@"
3262
+ else
3263
+ echo "Agente Lola nao encontrado: $LOLA_AGENT"
3264
+ echo "Rode: nimbus lola install"
3265
+ exit 1
3266
+ fi
3267
+ `;
3268
+ await Bun.write(lolaScript, unixScript);
3269
+ await Bun.$`chmod +x ${lolaScript}`;
3270
+ console.log(import_picocolors7.default.green(` Script lola criado em ${lolaScript}`));
3271
+ const pathEnv = process.env.PATH || "";
3272
+ if (!pathEnv.includes(".local/bin")) {
3273
+ console.log();
3274
+ console.log(import_picocolors7.default.yellow(" IMPORTANTE: Adicione ~/.local/bin ao seu PATH"));
3275
+ console.log(import_picocolors7.default.dim(' export PATH="$HOME/.local/bin:$PATH"'));
3276
+ }
3277
+ } else {
3278
+ console.log(import_picocolors7.default.green(" Script lola ja existe"));
3279
+ }
3280
+ }
3281
+ await installLolaMemoryMCP();
3282
+ const claudeDir = join3(HOME, ".claude");
3283
+ if (!existsSync2(USER_MEMORY)) {
3284
+ console.log();
3285
+ console.log(import_picocolors7.default.cyan(" Configurando USER_MEMORY.md..."));
3286
+ const gitUserResult = Bun.spawnSync(["git", "config", "user.name"], { stdout: "pipe" });
3287
+ const gitEmailResult = Bun.spawnSync(["git", "config", "user.email"], { stdout: "pipe" });
3288
+ const gitUser = gitUserResult.stdout.toString().trim() || "Dev";
3289
+ const gitEmail = gitEmailResult.stdout.toString().trim() || "";
3290
+ const hostname = process.env.HOSTNAME || process.env.COMPUTERNAME || "local";
3291
+ const today = new Date().toISOString().split("T")[0];
3292
+ await Bun.$`mkdir -p ${claudeDir}`;
3293
+ const content = `# User Memory
3294
+
3295
+ Memoria persistente para sessoes Claude Code
3296
+
3297
+ ---
3298
+
3299
+ ## Dev
3300
+
3301
+ **Nome:** ${gitUser}
3302
+ **Email:** ${gitEmail}
3303
+ **Maquina:** ${hostname}
3304
+ **Instalacao:** ${today}
3305
+
3306
+ ---
3307
+
3308
+ ## Configuracoes da Lola
3309
+
3310
+ \`\`\`
3311
+ lola_profile: millennial
3312
+ \`\`\`
3313
+
3314
+ ---
3315
+
3316
+ ## Ultima Sessao
3317
+
3318
+ (sera preenchido automaticamente)
3319
+
3320
+ ---
3321
+ `;
3322
+ await Bun.write(USER_MEMORY, content);
3323
+ console.log(import_picocolors7.default.green(` USER_MEMORY.md criado para ${gitUser}!`));
3324
+ }
3325
+ console.log();
3326
+ console.log(import_picocolors7.default.green(" Claude configurado!"));
3327
+ }
3030
3328
  async function lola(args) {
3031
3329
  const subcommand = args[0];
3032
3330
  if (!subcommand || subcommand === "install" || subcommand === "sync") {
3033
- await installLola();
3331
+ await installInteractive();
3034
3332
  } else if (subcommand === "onboard") {
3035
3333
  await onboardDev();
3036
3334
  } else if (subcommand === "quiz") {
@@ -3176,9 +3474,10 @@ ${import_picocolors8.default.bold("Analyze & Upgrade:")}
3176
3474
  upgrade tailwind Atualizar Tailwind CSS
3177
3475
 
3178
3476
  ${import_picocolors8.default.bold("Update (CLI):")}
3179
- update Atualizar para \xFAltima vers\xE3o
3180
- update 0.11.0 Instalar vers\xE3o espec\xEDfica
3181
- update --list Listar vers\xF5es dispon\xEDveis
3477
+ update Atualizar para ultima versao
3478
+ update 0.11.0 Instalar versao especifica
3479
+ update --list Listar versoes disponiveis
3480
+ update --force Forcar reinstalacao (limpa cache)
3182
3481
 
3183
3482
  ${import_picocolors8.default.bold("Op\xE7\xF5es:")}
3184
3483
  -y, --yes Aceitar padr\xF5es