@nimbuslab/cli 0.8.0 → 0.10.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
@@ -147,7 +147,7 @@ var require_src = __commonJS((exports, module) => {
147
147
  });
148
148
 
149
149
  // src/index.ts
150
- var import_picocolors4 = __toESM(require_picocolors(), 1);
150
+ var import_picocolors7 = __toESM(require_picocolors(), 1);
151
151
 
152
152
  // node_modules/@clack/core/dist/index.mjs
153
153
  var import_sisteransi = __toESM(require_src(), 1);
@@ -1888,9 +1888,580 @@ function showNextSteps(config) {
1888
1888
  console.log();
1889
1889
  }
1890
1890
 
1891
+ // src/commands/analyze.ts
1892
+ var import_picocolors4 = __toESM(require_picocolors(), 1);
1893
+ import { existsSync, readFileSync } from "fs";
1894
+ import { join as join2 } from "path";
1895
+ function detectPackageManager(dir) {
1896
+ if (existsSync(join2(dir, "bun.lockb")))
1897
+ return "bun";
1898
+ if (existsSync(join2(dir, "pnpm-lock.yaml")))
1899
+ return "pnpm";
1900
+ if (existsSync(join2(dir, "yarn.lock")))
1901
+ return "yarn";
1902
+ if (existsSync(join2(dir, "package-lock.json")))
1903
+ return "npm";
1904
+ return "unknown";
1905
+ }
1906
+ function detectMonorepo(dir, pkg) {
1907
+ if (existsSync(join2(dir, "turbo.json")))
1908
+ return "turborepo";
1909
+ if (existsSync(join2(dir, "nx.json")))
1910
+ return "nx";
1911
+ if (existsSync(join2(dir, "lerna.json")))
1912
+ return "lerna";
1913
+ if (pkg.workspaces)
1914
+ return "workspaces";
1915
+ return null;
1916
+ }
1917
+ function detectFramework(deps) {
1918
+ if (deps["next"])
1919
+ return { name: "nextjs", version: deps["next"] };
1920
+ if (deps["@angular/core"])
1921
+ return { name: "angular", version: deps["@angular/core"] };
1922
+ if (deps["vue"])
1923
+ return { name: "vue", version: deps["vue"] };
1924
+ if (deps["svelte"])
1925
+ return { name: "svelte", version: deps["svelte"] };
1926
+ if (deps["react"] && !deps["next"])
1927
+ return { name: "react", version: deps["react"] };
1928
+ return { name: null, version: null };
1929
+ }
1930
+ function detectStyling(deps, devDeps) {
1931
+ const styling = [];
1932
+ const allDeps = { ...deps, ...devDeps };
1933
+ if (allDeps["tailwindcss"])
1934
+ styling.push(`tailwind@${allDeps["tailwindcss"]}`);
1935
+ if (allDeps["styled-components"])
1936
+ styling.push("styled-components");
1937
+ if (allDeps["@emotion/react"])
1938
+ styling.push("emotion");
1939
+ if (allDeps["sass"])
1940
+ styling.push("sass");
1941
+ if (allDeps["less"])
1942
+ styling.push("less");
1943
+ return styling.length > 0 ? styling : ["css"];
1944
+ }
1945
+ function detectAuth(deps) {
1946
+ if (deps["better-auth"])
1947
+ return "better-auth";
1948
+ if (deps["next-auth"])
1949
+ return "next-auth";
1950
+ if (deps["@clerk/nextjs"])
1951
+ return "clerk";
1952
+ if (deps["@auth0/nextjs-auth0"])
1953
+ return "auth0";
1954
+ if (deps["@supabase/supabase-js"])
1955
+ return "supabase";
1956
+ return null;
1957
+ }
1958
+ function detectDatabase(deps) {
1959
+ if (deps["drizzle-orm"])
1960
+ return "drizzle";
1961
+ if (deps["@prisma/client"])
1962
+ return "prisma";
1963
+ if (deps["typeorm"])
1964
+ return "typeorm";
1965
+ if (deps["mongoose"])
1966
+ return "mongoose";
1967
+ if (deps["pg"])
1968
+ return "pg";
1969
+ if (deps["mysql2"])
1970
+ return "mysql";
1971
+ return null;
1972
+ }
1973
+ function generateRecommendations(result) {
1974
+ const recs = [];
1975
+ if (result.packageManager !== "bun") {
1976
+ recs.push(`Migrar ${result.packageManager} -> bun (nimbus codemod bun)`);
1977
+ }
1978
+ if (result.framework === "nextjs" && result.frameworkVersion) {
1979
+ const majorVersion = parseInt(result.frameworkVersion.replace(/[^0-9]/g, "").slice(0, 2));
1980
+ if (majorVersion < 16) {
1981
+ recs.push(`Atualizar Next.js ${result.frameworkVersion} -> 16 (nimbus upgrade next)`);
1982
+ }
1983
+ }
1984
+ const tailwind = result.styling.find((s) => s.startsWith("tailwind"));
1985
+ if (tailwind) {
1986
+ const version = tailwind.split("@")[1] || "";
1987
+ if (version.startsWith("3")) {
1988
+ recs.push(`Atualizar Tailwind 3 -> 4 (nimbus upgrade tailwind)`);
1989
+ }
1990
+ } else if (!result.styling.includes("tailwind")) {
1991
+ recs.push(`Considerar adicionar Tailwind CSS (nimbus add tailwind)`);
1992
+ }
1993
+ if (result.dependencies["react"]) {
1994
+ const reactVersion = result.dependencies["react"];
1995
+ if (reactVersion.startsWith("18") || reactVersion.startsWith("^18")) {
1996
+ recs.push(`Atualizar React 18 -> 19 (nimbus upgrade react)`);
1997
+ }
1998
+ }
1999
+ if (result.database === "prisma") {
2000
+ recs.push(`Considerar migrar Prisma -> Drizzle (nimbus codemod drizzle)`);
2001
+ } else if (!result.database && result.framework === "nextjs") {
2002
+ recs.push(`Considerar adicionar banco de dados (nimbus add db)`);
2003
+ }
2004
+ if (!result.auth && result.framework === "nextjs") {
2005
+ recs.push(`Considerar adicionar autenticacao (nimbus add auth)`);
2006
+ } else if (result.auth === "next-auth") {
2007
+ recs.push(`Considerar migrar NextAuth -> Better Auth`);
2008
+ }
2009
+ if (result.monorepo === "workspaces" && !result.monorepo) {
2010
+ recs.push(`Considerar usar Turborepo para monorepo (nimbus add monorepo)`);
2011
+ }
2012
+ return recs;
2013
+ }
2014
+ async function analyze(args) {
2015
+ const targetDir = args[0] || ".";
2016
+ const absoluteDir = targetDir.startsWith("/") ? targetDir : join2(process.cwd(), targetDir);
2017
+ console.log();
2018
+ console.log(import_picocolors4.default.cyan(" Analisando projeto..."));
2019
+ console.log();
2020
+ const pkgPath = join2(absoluteDir, "package.json");
2021
+ if (!existsSync(pkgPath)) {
2022
+ console.log(import_picocolors4.default.red(" Erro: package.json nao encontrado"));
2023
+ console.log(import_picocolors4.default.dim(` Diretorio: ${absoluteDir}`));
2024
+ process.exit(1);
2025
+ }
2026
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
2027
+ const deps = pkg.dependencies || {};
2028
+ const devDeps = pkg.devDependencies || {};
2029
+ const framework = detectFramework(deps);
2030
+ const result = {
2031
+ name: pkg.name || "unknown",
2032
+ version: pkg.version || "0.0.0",
2033
+ framework: framework.name,
2034
+ frameworkVersion: framework.version,
2035
+ styling: detectStyling(deps, devDeps),
2036
+ packageManager: detectPackageManager(absoluteDir),
2037
+ monorepo: detectMonorepo(absoluteDir, pkg),
2038
+ auth: detectAuth(deps),
2039
+ database: detectDatabase(deps),
2040
+ typescript: existsSync(join2(absoluteDir, "tsconfig.json")),
2041
+ dependencies: deps,
2042
+ devDependencies: devDeps,
2043
+ recommendations: []
2044
+ };
2045
+ result.recommendations = generateRecommendations(result);
2046
+ console.log(import_picocolors4.default.bold(" Projeto: ") + import_picocolors4.default.cyan(result.name) + import_picocolors4.default.dim(` v${result.version}`));
2047
+ console.log();
2048
+ console.log(import_picocolors4.default.bold(" Stack Detectada:"));
2049
+ console.log(` Framework: ${result.framework ? import_picocolors4.default.green(result.framework + "@" + result.frameworkVersion) : import_picocolors4.default.dim("nenhum")}`);
2050
+ console.log(` Styling: ${result.styling.map((s) => import_picocolors4.default.green(s)).join(", ")}`);
2051
+ console.log(` Package Manager: ${result.packageManager === "bun" ? import_picocolors4.default.green(result.packageManager) : import_picocolors4.default.yellow(result.packageManager)}`);
2052
+ console.log(` TypeScript: ${result.typescript ? import_picocolors4.default.green("sim") : import_picocolors4.default.dim("nao")}`);
2053
+ console.log(` Monorepo: ${result.monorepo ? import_picocolors4.default.green(result.monorepo) : import_picocolors4.default.dim("nao")}`);
2054
+ console.log(` Auth: ${result.auth ? import_picocolors4.default.green(result.auth) : import_picocolors4.default.dim("nenhum")}`);
2055
+ console.log(` Database: ${result.database ? import_picocolors4.default.green(result.database) : import_picocolors4.default.dim("nenhum")}`);
2056
+ console.log();
2057
+ if (result.recommendations.length > 0) {
2058
+ console.log(import_picocolors4.default.bold(" Recomendacoes:"));
2059
+ result.recommendations.forEach((rec, i) => {
2060
+ console.log(import_picocolors4.default.yellow(` ${i + 1}. ${rec}`));
2061
+ });
2062
+ console.log();
2063
+ } else {
2064
+ console.log(import_picocolors4.default.green(" Projeto ja esta na stack recomendada!"));
2065
+ console.log();
2066
+ }
2067
+ if (args.includes("--json")) {
2068
+ console.log(import_picocolors4.default.dim(" JSON:"));
2069
+ console.log(JSON.stringify(result, null, 2));
2070
+ }
2071
+ return result;
2072
+ }
2073
+
2074
+ // src/commands/upgrade.ts
2075
+ var import_picocolors5 = __toESM(require_picocolors(), 1);
2076
+ var UPGRADE_PLANS = {
2077
+ next: (current) => {
2078
+ const major = parseInt(current.replace(/[^0-9]/g, "").slice(0, 2));
2079
+ if (major >= 16)
2080
+ return null;
2081
+ return {
2082
+ current,
2083
+ target: "16.x",
2084
+ complexity: major < 15 ? "high" : "medium",
2085
+ breakingChanges: [
2086
+ "next/image: Mudancas na API de otimizacao",
2087
+ "Middleware: Novo formato de config",
2088
+ "next.config: Algumas opcoes depreciadas",
2089
+ "Turbopack: Agora e o bundler padrao"
2090
+ ],
2091
+ steps: [
2092
+ "Atualizar next para ^16.0.0",
2093
+ "Atualizar react para ^19.0.0",
2094
+ "Atualizar react-dom para ^19.0.0",
2095
+ "Revisar next.config.ts",
2096
+ "Testar build: bun run build",
2097
+ "Testar dev: bun dev"
2098
+ ]
2099
+ };
2100
+ },
2101
+ react: (current) => {
2102
+ if (current.startsWith("19") || current.startsWith("^19"))
2103
+ return null;
2104
+ return {
2105
+ current,
2106
+ target: "19.x",
2107
+ complexity: "medium",
2108
+ breakingChanges: [
2109
+ "forwardRef: Nao mais necessario, ref e prop regular",
2110
+ "useContext: Pode ser substituido por use(Context)",
2111
+ "Suspense: Mudancas em fallback behavior",
2112
+ "Async components: Novo suporte nativo"
2113
+ ],
2114
+ steps: [
2115
+ "Atualizar react para ^19.0.0",
2116
+ "Atualizar react-dom para ^19.0.0",
2117
+ "Atualizar @types/react para ^19.0.0",
2118
+ "Remover forwardRef (usar ref como prop)",
2119
+ "Revisar Suspense boundaries",
2120
+ "Testar todos os componentes"
2121
+ ]
2122
+ };
2123
+ },
2124
+ tailwind: (current) => {
2125
+ if (current.startsWith("4") || current.startsWith("^4"))
2126
+ return null;
2127
+ return {
2128
+ current,
2129
+ target: "4.x",
2130
+ complexity: "medium",
2131
+ breakingChanges: [
2132
+ "Config: Agora e CSS-first (nao mais tailwind.config.js)",
2133
+ "@apply: Sintaxe mudou",
2134
+ "Cores: Novo sistema de tokens",
2135
+ "Plugins: API diferente"
2136
+ ],
2137
+ steps: [
2138
+ "Atualizar tailwindcss para ^4.0.0",
2139
+ "Converter tailwind.config.js para CSS",
2140
+ "Atualizar globals.css com @import 'tailwindcss'",
2141
+ "Revisar @apply usages",
2142
+ "Atualizar plugins para v4",
2143
+ "Testar todas as paginas"
2144
+ ]
2145
+ };
2146
+ },
2147
+ bun: () => ({
2148
+ current: "pnpm/npm/yarn",
2149
+ target: "bun",
2150
+ complexity: "low",
2151
+ breakingChanges: [
2152
+ "Lockfile: Formato diferente (bun.lockb)",
2153
+ "Scripts: Alguns podem precisar ajuste",
2154
+ "Workspaces: Sintaxe levemente diferente"
2155
+ ],
2156
+ steps: [
2157
+ "Remover node_modules",
2158
+ "Remover pnpm-lock.yaml / package-lock.json / yarn.lock",
2159
+ "Executar: bun install",
2160
+ "Atualizar scripts no package.json (npx -> bunx)",
2161
+ "Atualizar CI/CD configs",
2162
+ "Testar: bun dev, bun build"
2163
+ ]
2164
+ }),
2165
+ drizzle: () => ({
2166
+ current: "prisma",
2167
+ target: "drizzle",
2168
+ complexity: "high",
2169
+ breakingChanges: [
2170
+ "Schema: Formato TypeScript (nao mais .prisma)",
2171
+ "Queries: API completamente diferente",
2172
+ "Migrations: Sistema diferente",
2173
+ "Relations: Declaracao diferente"
2174
+ ],
2175
+ steps: [
2176
+ "Instalar drizzle-orm e drizzle-kit",
2177
+ "Converter schema.prisma para drizzle/schema.ts",
2178
+ "Configurar drizzle.config.ts",
2179
+ "Gerar migrations: bunx drizzle-kit generate",
2180
+ "Atualizar todas as queries",
2181
+ "Atualizar auth config (se usar)",
2182
+ "Remover @prisma/client e prisma",
2183
+ "Testar todas as operacoes de banco"
2184
+ ]
2185
+ })
2186
+ };
2187
+ async function upgrade(args) {
2188
+ const showPlan = args.includes("--plan");
2189
+ const target = args.find((a) => !a.startsWith("-"));
2190
+ console.log();
2191
+ if (showPlan || !target) {
2192
+ console.log(import_picocolors5.default.cyan(" Analisando projeto para plano de upgrade..."));
2193
+ console.log();
2194
+ const analysis = await analyze([".", "--quiet"]);
2195
+ console.log(import_picocolors5.default.bold(" Upgrades Disponiveis:"));
2196
+ console.log();
2197
+ let hasUpgrades = false;
2198
+ if (analysis.frameworkVersion && analysis.framework === "nextjs") {
2199
+ const planFn = UPGRADE_PLANS["next"];
2200
+ if (planFn) {
2201
+ const plan = planFn(analysis.frameworkVersion);
2202
+ if (plan) {
2203
+ hasUpgrades = true;
2204
+ printUpgradePlan("Next.js", plan);
2205
+ }
2206
+ }
2207
+ }
2208
+ if (analysis.dependencies["react"]) {
2209
+ const planFn = UPGRADE_PLANS["react"];
2210
+ if (planFn) {
2211
+ const plan = planFn(analysis.dependencies["react"]);
2212
+ if (plan) {
2213
+ hasUpgrades = true;
2214
+ printUpgradePlan("React", plan);
2215
+ }
2216
+ }
2217
+ }
2218
+ const tailwindDep = analysis.dependencies["tailwindcss"] || analysis.devDependencies["tailwindcss"];
2219
+ if (tailwindDep) {
2220
+ const planFn = UPGRADE_PLANS["tailwind"];
2221
+ if (planFn) {
2222
+ const plan = planFn(tailwindDep);
2223
+ if (plan) {
2224
+ hasUpgrades = true;
2225
+ printUpgradePlan("Tailwind CSS", plan);
2226
+ }
2227
+ }
2228
+ }
2229
+ if (analysis.packageManager !== "bun") {
2230
+ const planFn = UPGRADE_PLANS["bun"];
2231
+ if (planFn) {
2232
+ const plan = planFn("");
2233
+ if (plan) {
2234
+ hasUpgrades = true;
2235
+ printUpgradePlan("Package Manager", plan);
2236
+ }
2237
+ }
2238
+ }
2239
+ if (analysis.database === "prisma") {
2240
+ const planFn = UPGRADE_PLANS["drizzle"];
2241
+ if (planFn) {
2242
+ const plan = planFn("");
2243
+ if (plan) {
2244
+ hasUpgrades = true;
2245
+ printUpgradePlan("Database", plan);
2246
+ }
2247
+ }
2248
+ }
2249
+ if (!hasUpgrades) {
2250
+ console.log(import_picocolors5.default.green(" Projeto ja esta atualizado!"));
2251
+ }
2252
+ console.log();
2253
+ console.log(import_picocolors5.default.dim(" Para executar um upgrade especifico:"));
2254
+ console.log(import_picocolors5.default.dim(" nimbus upgrade next"));
2255
+ console.log(import_picocolors5.default.dim(" nimbus upgrade tailwind"));
2256
+ console.log(import_picocolors5.default.dim(" nimbus upgrade bun"));
2257
+ console.log();
2258
+ return;
2259
+ }
2260
+ console.log(import_picocolors5.default.yellow(` Upgrade ${target} ainda nao implementado.`));
2261
+ console.log(import_picocolors5.default.dim(" Por enquanto, siga os passos do --plan manualmente."));
2262
+ console.log();
2263
+ }
2264
+ function printUpgradePlan(name, plan) {
2265
+ const complexityColor = {
2266
+ low: import_picocolors5.default.green,
2267
+ medium: import_picocolors5.default.yellow,
2268
+ high: import_picocolors5.default.red
2269
+ };
2270
+ console.log(` ${import_picocolors5.default.bold(name)}`);
2271
+ console.log(` ${import_picocolors5.default.dim("Atual:")} ${plan.current} ${import_picocolors5.default.dim("->")} ${import_picocolors5.default.cyan(plan.target)}`);
2272
+ console.log(` ${import_picocolors5.default.dim("Complexidade:")} ${complexityColor[plan.complexity](plan.complexity)}`);
2273
+ console.log();
2274
+ console.log(` ${import_picocolors5.default.dim("Breaking Changes:")}`);
2275
+ plan.breakingChanges.forEach((bc) => {
2276
+ console.log(` ${import_picocolors5.default.yellow("!")} ${bc}`);
2277
+ });
2278
+ console.log();
2279
+ console.log(` ${import_picocolors5.default.dim("Passos:")}`);
2280
+ plan.steps.forEach((step, i) => {
2281
+ console.log(` ${import_picocolors5.default.dim(`${i + 1}.`)} ${step}`);
2282
+ });
2283
+ console.log();
2284
+ }
2285
+
2286
+ // src/commands/lola.ts
2287
+ var import_picocolors6 = __toESM(require_picocolors(), 1);
2288
+ import { existsSync as existsSync2 } from "fs";
2289
+ import { join as join3 } from "path";
2290
+ var LOLA_DIR = join3(process.env.HOME || "~", ".lola");
2291
+ var LOLA_REPO = "git@github.com:nimbuslab/lola.git";
2292
+ var USER_MEMORY = join3(process.env.HOME || "~", ".claude", "USER_MEMORY.md");
2293
+ async function installLola() {
2294
+ console.log();
2295
+ console.log(import_picocolors6.default.cyan(" Lola - Code Agent da nimbuslab"));
2296
+ console.log(import_picocolors6.default.dim(" ==============================="));
2297
+ console.log();
2298
+ const isUpdate = existsSync2(LOLA_DIR);
2299
+ if (isUpdate) {
2300
+ console.log(import_picocolors6.default.dim(` Lola ja instalada em ${LOLA_DIR}`));
2301
+ console.log(import_picocolors6.default.cyan(" Atualizando..."));
2302
+ const result = Bun.spawnSync(["git", "pull", "--quiet"], {
2303
+ cwd: LOLA_DIR,
2304
+ stdout: "inherit",
2305
+ stderr: "inherit"
2306
+ });
2307
+ if (result.exitCode !== 0) {
2308
+ console.log(import_picocolors6.default.red(" Erro ao atualizar Lola"));
2309
+ process.exit(1);
2310
+ }
2311
+ console.log(import_picocolors6.default.green(" Atualizado!"));
2312
+ } else {
2313
+ console.log(import_picocolors6.default.cyan(` Instalando Lola em ${LOLA_DIR}...`));
2314
+ const result = Bun.spawnSync(["git", "clone", "--quiet", LOLA_REPO, LOLA_DIR], {
2315
+ stdout: "inherit",
2316
+ stderr: "inherit"
2317
+ });
2318
+ if (result.exitCode !== 0) {
2319
+ console.log(import_picocolors6.default.red(" Erro ao clonar repositorio"));
2320
+ console.log(import_picocolors6.default.dim(" Verifique se tem acesso ao repo nimbuslab/lola"));
2321
+ process.exit(1);
2322
+ }
2323
+ console.log(import_picocolors6.default.green(" Instalado!"));
2324
+ }
2325
+ const claudeDir = join3(process.env.HOME || "~", ".claude");
2326
+ if (!existsSync2(USER_MEMORY)) {
2327
+ console.log();
2328
+ console.log(import_picocolors6.default.cyan(" Criando USER_MEMORY.md..."));
2329
+ await Bun.$`mkdir -p ${claudeDir}`;
2330
+ const content = `# User Memory
2331
+
2332
+ Memoria persistente para sessoes Claude Code
2333
+
2334
+ ---
2335
+
2336
+ ## Configuracoes da Lola
2337
+
2338
+ \`\`\`
2339
+ lola_profile: millennial
2340
+ \`\`\`
2341
+
2342
+ ---
2343
+
2344
+ ## Ultima Sessao
2345
+
2346
+ (sera preenchido automaticamente)
2347
+
2348
+ ---
2349
+ `;
2350
+ await Bun.write(USER_MEMORY, content);
2351
+ console.log(import_picocolors6.default.green(" USER_MEMORY.md criado!"));
2352
+ }
2353
+ console.log();
2354
+ console.log(import_picocolors6.default.green(" Instalacao concluida!"));
2355
+ console.log();
2356
+ console.log(import_picocolors6.default.bold(" Para usar a Lola:"));
2357
+ console.log(import_picocolors6.default.dim(" lola ") + import_picocolors6.default.white("# Iniciar sessao"));
2358
+ console.log(import_picocolors6.default.dim(' lola suggest "x" ') + import_picocolors6.default.white("# Sugerir melhoria"));
2359
+ console.log();
2360
+ console.log(import_picocolors6.default.bold(" Para mudar perfil, edite ~/.claude/USER_MEMORY.md:"));
2361
+ console.log(import_picocolors6.default.dim(" lola_profile: millennial|genz|profissional|nerd|chill"));
2362
+ console.log();
2363
+ }
2364
+ async function suggestImprovement(message) {
2365
+ if (!message) {
2366
+ console.log(import_picocolors6.default.red(" Erro: forne\xE7a uma mensagem"));
2367
+ console.log(import_picocolors6.default.dim(' Uso: nimbus lola suggest "sua sugestao aqui"'));
2368
+ process.exit(1);
2369
+ }
2370
+ const ghCheck = Bun.spawnSync(["which", "gh"]);
2371
+ if (ghCheck.exitCode !== 0) {
2372
+ console.log(import_picocolors6.default.red(" Erro: GitHub CLI (gh) nao encontrado"));
2373
+ console.log(import_picocolors6.default.dim(" Instale: https://cli.github.com"));
2374
+ process.exit(1);
2375
+ }
2376
+ const authCheck = Bun.spawnSync(["gh", "auth", "status"], {
2377
+ stdout: "pipe",
2378
+ stderr: "pipe"
2379
+ });
2380
+ if (authCheck.exitCode !== 0) {
2381
+ console.log(import_picocolors6.default.red(" Erro: GitHub CLI nao autenticado"));
2382
+ console.log(import_picocolors6.default.dim(" Execute: gh auth login"));
2383
+ process.exit(1);
2384
+ }
2385
+ const gitUser = Bun.spawnSync(["git", "config", "user.name"], { stdout: "pipe" });
2386
+ const gitEmail = Bun.spawnSync(["git", "config", "user.email"], { stdout: "pipe" });
2387
+ const userName = gitUser.stdout.toString().trim() || "Dev";
2388
+ const userEmail = gitEmail.stdout.toString().trim() || "";
2389
+ console.log();
2390
+ console.log(import_picocolors6.default.cyan(" Criando sugestao..."));
2391
+ const date = new Date().toISOString().split("T")[0];
2392
+ const body = `## Sugestao
2393
+
2394
+ ${message}
2395
+
2396
+ ---
2397
+
2398
+ **Enviado por:** ${userName}
2399
+ **Email:** ${userEmail}
2400
+ **Data:** ${date}
2401
+
2402
+ ---
2403
+ *Criado via \`nimbus lola suggest\`*`;
2404
+ const title = `Sugestao: ${message.slice(0, 50)}${message.length > 50 ? "..." : ""}`;
2405
+ const result = Bun.spawnSync([
2406
+ "gh",
2407
+ "issue",
2408
+ "create",
2409
+ "--repo",
2410
+ "nimbuslab/lola",
2411
+ "--title",
2412
+ title,
2413
+ "--body",
2414
+ body,
2415
+ "--label",
2416
+ "sugestao"
2417
+ ], {
2418
+ stdout: "inherit",
2419
+ stderr: "inherit"
2420
+ });
2421
+ if (result.exitCode !== 0) {
2422
+ console.log(import_picocolors6.default.red(" Erro ao criar issue"));
2423
+ process.exit(1);
2424
+ }
2425
+ console.log();
2426
+ console.log(import_picocolors6.default.green(" Sugestao enviada! Hugo vai revisar."));
2427
+ console.log();
2428
+ }
2429
+ async function lola(args) {
2430
+ const subcommand = args[0];
2431
+ if (!subcommand || subcommand === "install" || subcommand === "sync") {
2432
+ await installLola();
2433
+ } else if (subcommand === "suggest") {
2434
+ const message = args.slice(1).join(" ");
2435
+ await suggestImprovement(message);
2436
+ } else if (subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
2437
+ showLolaHelp();
2438
+ } else {
2439
+ console.log(import_picocolors6.default.red(` Subcomando desconhecido: ${subcommand}`));
2440
+ showLolaHelp();
2441
+ process.exit(1);
2442
+ }
2443
+ }
2444
+ function showLolaHelp() {
2445
+ console.log();
2446
+ console.log(import_picocolors6.default.bold(" Lola - Code Agent da nimbuslab"));
2447
+ console.log();
2448
+ console.log(import_picocolors6.default.bold(" Uso:") + " nimbus lola [subcomando]");
2449
+ console.log();
2450
+ console.log(import_picocolors6.default.bold(" Subcomandos:"));
2451
+ console.log(import_picocolors6.default.dim(" install ") + import_picocolors6.default.white("Instalar/atualizar Lola"));
2452
+ console.log(import_picocolors6.default.dim(" sync ") + import_picocolors6.default.white("Alias para install"));
2453
+ console.log(import_picocolors6.default.dim(' suggest "msg" ') + import_picocolors6.default.white("Sugerir melhoria (cria issue)"));
2454
+ console.log(import_picocolors6.default.dim(" help ") + import_picocolors6.default.white("Mostrar esta ajuda"));
2455
+ console.log();
2456
+ console.log(import_picocolors6.default.bold(" Exemplos:"));
2457
+ console.log(import_picocolors6.default.dim(" $ nimbus lola install"));
2458
+ console.log(import_picocolors6.default.dim(' $ nimbus lola suggest "adicionar suporte a X"'));
2459
+ console.log();
2460
+ }
2461
+
1891
2462
  // src/index.ts
1892
2463
  var PACKAGE_NAME = "@nimbuslab/cli";
1893
- var CURRENT_VERSION = "0.8.0";
2464
+ var CURRENT_VERSION = "0.9.0";
1894
2465
  var LOGO = `
1895
2466
  \u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
1896
2467
  \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
@@ -1926,18 +2497,18 @@ function showUpdateNotice(latestVersion) {
1926
2497
  const line2 = ` Update with: ${command}`;
1927
2498
  const maxLen = Math.max(line1.length, line2.length);
1928
2499
  const border = "\u2500".repeat(maxLen + 2);
1929
- console.log(import_picocolors4.default.yellow(` \u250C${border}\u2510`));
1930
- console.log(import_picocolors4.default.yellow(` \u2502`) + import_picocolors4.default.white(line1.padEnd(maxLen + 1)) + import_picocolors4.default.yellow(`\u2502`));
1931
- console.log(import_picocolors4.default.yellow(` \u2502`) + import_picocolors4.default.cyan(line2.padEnd(maxLen + 1)) + import_picocolors4.default.yellow(`\u2502`));
1932
- console.log(import_picocolors4.default.yellow(` \u2514${border}\u2518`));
2500
+ console.log(import_picocolors7.default.yellow(` \u250C${border}\u2510`));
2501
+ console.log(import_picocolors7.default.yellow(` \u2502`) + import_picocolors7.default.white(line1.padEnd(maxLen + 1)) + import_picocolors7.default.yellow(`\u2502`));
2502
+ console.log(import_picocolors7.default.yellow(` \u2502`) + import_picocolors7.default.cyan(line2.padEnd(maxLen + 1)) + import_picocolors7.default.yellow(`\u2502`));
2503
+ console.log(import_picocolors7.default.yellow(` \u2514${border}\u2518`));
1933
2504
  console.log();
1934
2505
  }
1935
2506
  async function main() {
1936
2507
  const args = process.argv.slice(2);
1937
2508
  const command = args[0];
1938
- console.log(import_picocolors4.default.cyan(LOGO));
1939
- console.log(import_picocolors4.default.white(" nimbuslab CLI"));
1940
- console.log(import_picocolors4.default.dim(" Create awesome projects"));
2509
+ console.log(import_picocolors7.default.cyan(LOGO));
2510
+ console.log(import_picocolors7.default.white(" nimbuslab CLI"));
2511
+ console.log(import_picocolors7.default.dim(" Create awesome projects"));
1941
2512
  console.log();
1942
2513
  const latestVersion = await checkForUpdates();
1943
2514
  if (latestVersion) {
@@ -1945,46 +2516,69 @@ async function main() {
1945
2516
  }
1946
2517
  if (!command || command === "create") {
1947
2518
  await create(args.slice(1));
2519
+ } else if (command === "analyze") {
2520
+ await analyze(args.slice(1));
2521
+ } else if (command === "upgrade") {
2522
+ await upgrade(args.slice(1));
2523
+ } else if (command === "lola") {
2524
+ await lola(args.slice(1));
1948
2525
  } else if (command === "help" || command === "--help" || command === "-h") {
1949
2526
  showHelp();
1950
2527
  } else if (command === "version" || command === "--version" || command === "-v") {
1951
2528
  showVersion();
1952
2529
  } else {
1953
- console.log(import_picocolors4.default.red(`Unknown command: ${command}`));
2530
+ console.log(import_picocolors7.default.red(`Unknown command: ${command}`));
1954
2531
  showHelp();
1955
2532
  process.exit(1);
1956
2533
  }
1957
2534
  }
1958
2535
  function showHelp() {
1959
2536
  console.log(`
1960
- ${import_picocolors4.default.bold("Usage:")} nimbus [command] [options]
2537
+ ${import_picocolors7.default.bold("Usage:")} nimbus [command] [options]
1961
2538
 
1962
- ${import_picocolors4.default.bold("Commands:")}
2539
+ ${import_picocolors7.default.bold("Commands:")}
1963
2540
  create [name] Create a new project
2541
+ analyze [dir] Analyze project stack
2542
+ upgrade [target] Upgrade dependencies
2543
+ lola [action] Lola - Code Agent
1964
2544
  help Show this help
1965
2545
  version Show version
1966
2546
 
1967
- ${import_picocolors4.default.bold("Templates:")}
2547
+ ${import_picocolors7.default.bold("Templates:")}
1968
2548
  --landing Landing page (Next.js 16 + Tailwind 4 + shadcn)
1969
- --app Web app (Landing + Better Auth + Prisma)
2549
+ --app Web app (Landing + Better Auth + Drizzle)
1970
2550
  --turborepo Monorepo (Turborepo + apps/packages)
1971
2551
 
1972
- ${import_picocolors4.default.bold("Options:")}
2552
+ ${import_picocolors7.default.bold("Analyze & Upgrade:")}
2553
+ analyze . Detect stack and show recommendations
2554
+ analyze --json Output as JSON
2555
+ upgrade --plan Show upgrade plan
2556
+ upgrade next Upgrade Next.js
2557
+ upgrade tailwind Upgrade Tailwind CSS
2558
+
2559
+ ${import_picocolors7.default.bold("Options:")}
1973
2560
  -y, --yes Accept defaults
1974
2561
  --no-git Don't initialize Git
1975
2562
  --no-install Don't install dependencies
1976
2563
  --template <url> Use custom template
1977
2564
 
1978
- ${import_picocolors4.default.bold("Examples:")}
1979
- ${import_picocolors4.default.dim("$")} nimbus create my-landing --landing
1980
- ${import_picocolors4.default.dim("$")} nimbus create my-app --app
1981
- ${import_picocolors4.default.dim("$")} nimbus create my-monorepo --turborepo
2565
+ ${import_picocolors7.default.bold("Lola (Code Agent):")}
2566
+ lola install Install/update Lola
2567
+ lola suggest Suggest improvement (creates issue)
2568
+
2569
+ ${import_picocolors7.default.bold("Examples:")}
2570
+ ${import_picocolors7.default.dim("$")} nimbus create my-landing --landing
2571
+ ${import_picocolors7.default.dim("$")} nimbus create my-app --app
2572
+ ${import_picocolors7.default.dim("$")} nimbus analyze ./my-project
2573
+ ${import_picocolors7.default.dim("$")} nimbus upgrade --plan
2574
+ ${import_picocolors7.default.dim("$")} nimbus lola install
2575
+ ${import_picocolors7.default.dim("$")} nimbus lola suggest "add support for X"
1982
2576
  `);
1983
2577
  }
1984
2578
  function showVersion() {
1985
2579
  console.log(`${PACKAGE_NAME} v${CURRENT_VERSION}`);
1986
2580
  }
1987
2581
  main().catch((err) => {
1988
- console.error(import_picocolors4.default.red("Erro:"), err.message);
2582
+ console.error(import_picocolors7.default.red("Erro:"), err.message);
1989
2583
  process.exit(1);
1990
2584
  });