@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/MIGRATION-ROADMAP.md +201 -0
- package/README.md +77 -64
- package/dist/index.js +614 -20
- package/docs/analyze.md +148 -0
- package/docs/create.md +219 -0
- package/docs/migrate.md +177 -0
- package/docs/package.md +229 -0
- package/docs/upgrade.md +152 -0
- package/package.json +1 -1
- package/src/commands/analyze.ts +210 -0
- package/src/commands/lola.ts +201 -0
- package/src/commands/upgrade.ts +251 -0
- package/src/index.ts +29 -3
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
|
|
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.
|
|
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(
|
|
1930
|
-
console.log(
|
|
1931
|
-
console.log(
|
|
1932
|
-
console.log(
|
|
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(
|
|
1939
|
-
console.log(
|
|
1940
|
-
console.log(
|
|
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(
|
|
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
|
-
${
|
|
2537
|
+
${import_picocolors7.default.bold("Usage:")} nimbus [command] [options]
|
|
1961
2538
|
|
|
1962
|
-
${
|
|
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
|
-
${
|
|
2547
|
+
${import_picocolors7.default.bold("Templates:")}
|
|
1968
2548
|
--landing Landing page (Next.js 16 + Tailwind 4 + shadcn)
|
|
1969
|
-
--app Web app (Landing + Better Auth +
|
|
2549
|
+
--app Web app (Landing + Better Auth + Drizzle)
|
|
1970
2550
|
--turborepo Monorepo (Turborepo + apps/packages)
|
|
1971
2551
|
|
|
1972
|
-
${
|
|
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
|
-
${
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
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(
|
|
2582
|
+
console.error(import_picocolors7.default.red("Erro:"), err.message);
|
|
1989
2583
|
process.exit(1);
|
|
1990
2584
|
});
|