@nimbuslab/cli 0.9.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -64
- package/dist/index.js +252 -21
- 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/lola.ts +201 -0
- package/src/index.ts +14 -1
package/docs/upgrade.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# nimbus upgrade
|
|
2
|
+
|
|
3
|
+
Planeja e executa upgrades de dependencias para a stack nimbuslab.
|
|
4
|
+
|
|
5
|
+
## Uso
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Ver plano completo de upgrades
|
|
9
|
+
nimbus upgrade --plan
|
|
10
|
+
|
|
11
|
+
# Upgrade especifico (em desenvolvimento)
|
|
12
|
+
nimbus upgrade next
|
|
13
|
+
nimbus upgrade react
|
|
14
|
+
nimbus upgrade tailwind
|
|
15
|
+
nimbus upgrade bun
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Upgrades Suportados
|
|
19
|
+
|
|
20
|
+
### Next.js 14/15 -> 16
|
|
21
|
+
|
|
22
|
+
| Aspecto | Detalhes |
|
|
23
|
+
|---------|----------|
|
|
24
|
+
| Complexidade | Media |
|
|
25
|
+
| Breaking Changes | next/image API, middleware, turbopack |
|
|
26
|
+
| Tempo Estimado | 1-2 horas |
|
|
27
|
+
|
|
28
|
+
**Passos:**
|
|
29
|
+
1. Atualizar next para ^16.0.0
|
|
30
|
+
2. Atualizar react para ^19.0.0
|
|
31
|
+
3. Atualizar react-dom para ^19.0.0
|
|
32
|
+
4. Revisar next.config.ts
|
|
33
|
+
5. Testar build e dev
|
|
34
|
+
|
|
35
|
+
### React 18 -> 19
|
|
36
|
+
|
|
37
|
+
| Aspecto | Detalhes |
|
|
38
|
+
|---------|----------|
|
|
39
|
+
| Complexidade | Media |
|
|
40
|
+
| Breaking Changes | forwardRef, Suspense, async components |
|
|
41
|
+
| Tempo Estimado | 1-2 horas |
|
|
42
|
+
|
|
43
|
+
**Passos:**
|
|
44
|
+
1. Atualizar react e react-dom para ^19.0.0
|
|
45
|
+
2. Remover forwardRef (ref agora e prop regular)
|
|
46
|
+
3. Atualizar @types/react
|
|
47
|
+
4. Revisar Suspense boundaries
|
|
48
|
+
|
|
49
|
+
### Tailwind 3 -> 4
|
|
50
|
+
|
|
51
|
+
| Aspecto | Detalhes |
|
|
52
|
+
|---------|----------|
|
|
53
|
+
| Complexidade | Media |
|
|
54
|
+
| Breaking Changes | Config em CSS, @apply syntax |
|
|
55
|
+
| Tempo Estimado | 2-4 horas |
|
|
56
|
+
|
|
57
|
+
**Passos:**
|
|
58
|
+
1. Atualizar tailwindcss para ^4.0.0
|
|
59
|
+
2. Converter tailwind.config.js para CSS
|
|
60
|
+
3. Atualizar globals.css com @import 'tailwindcss'
|
|
61
|
+
4. Revisar @apply usages
|
|
62
|
+
5. Atualizar plugins
|
|
63
|
+
|
|
64
|
+
### pnpm/npm/yarn -> bun
|
|
65
|
+
|
|
66
|
+
| Aspecto | Detalhes |
|
|
67
|
+
|---------|----------|
|
|
68
|
+
| Complexidade | Baixa |
|
|
69
|
+
| Breaking Changes | Lockfile, alguns scripts |
|
|
70
|
+
| Tempo Estimado | 30 min |
|
|
71
|
+
|
|
72
|
+
**Passos:**
|
|
73
|
+
1. Remover node_modules
|
|
74
|
+
2. Remover lockfile antigo
|
|
75
|
+
3. Executar bun install
|
|
76
|
+
4. Atualizar scripts (npx -> bunx)
|
|
77
|
+
5. Atualizar CI/CD
|
|
78
|
+
|
|
79
|
+
### Prisma -> Drizzle
|
|
80
|
+
|
|
81
|
+
| Aspecto | Detalhes |
|
|
82
|
+
|---------|----------|
|
|
83
|
+
| Complexidade | Alta |
|
|
84
|
+
| Breaking Changes | Schema, queries, migrations |
|
|
85
|
+
| Tempo Estimado | 4-8 horas |
|
|
86
|
+
|
|
87
|
+
**Passos:**
|
|
88
|
+
1. Instalar drizzle-orm e drizzle-kit
|
|
89
|
+
2. Converter schema.prisma para drizzle
|
|
90
|
+
3. Configurar drizzle.config.ts
|
|
91
|
+
4. Gerar migrations
|
|
92
|
+
5. Atualizar todas as queries
|
|
93
|
+
6. Atualizar auth config
|
|
94
|
+
|
|
95
|
+
## Exemplo de Output
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
Upgrades Disponiveis:
|
|
99
|
+
|
|
100
|
+
Next.js
|
|
101
|
+
Atual: 15.0.2 -> 16.x
|
|
102
|
+
Complexidade: media
|
|
103
|
+
|
|
104
|
+
Breaking Changes:
|
|
105
|
+
! next/image: Mudancas na API de otimizacao
|
|
106
|
+
! Middleware: Novo formato de config
|
|
107
|
+
! Turbopack: Agora e o bundler padrao
|
|
108
|
+
|
|
109
|
+
Passos:
|
|
110
|
+
1. Atualizar next para ^16.0.0
|
|
111
|
+
2. Atualizar react para ^19.0.0
|
|
112
|
+
3. Revisar next.config.ts
|
|
113
|
+
4. Testar build: bun run build
|
|
114
|
+
|
|
115
|
+
React
|
|
116
|
+
Atual: 18.2.0 -> 19.x
|
|
117
|
+
Complexidade: media
|
|
118
|
+
|
|
119
|
+
Breaking Changes:
|
|
120
|
+
! forwardRef: Nao mais necessario
|
|
121
|
+
! Suspense: Mudancas em fallback
|
|
122
|
+
! Async components: Novo suporte
|
|
123
|
+
|
|
124
|
+
Passos:
|
|
125
|
+
1. Atualizar react para ^19.0.0
|
|
126
|
+
2. Remover forwardRef
|
|
127
|
+
3. Revisar Suspense boundaries
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Codemods (Em Desenvolvimento)
|
|
131
|
+
|
|
132
|
+
Codemods sao transformacoes automaticas de codigo usando AST:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Futuros comandos
|
|
136
|
+
nimbus codemod tailwind-v4 # Transforma Tailwind 3 -> 4
|
|
137
|
+
nimbus codemod react-19 # Transforma React 18 -> 19
|
|
138
|
+
nimbus codemod drizzle # Transforma Prisma -> Drizzle
|
|
139
|
+
nimbus codemod bun # Transforma para Bun
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Estrategia de Upgrade
|
|
143
|
+
|
|
144
|
+
1. **Sempre** fazer backup/branch antes
|
|
145
|
+
2. **Sempre** rodar `nimbus analyze` primeiro
|
|
146
|
+
3. **Sempre** testar apos cada upgrade
|
|
147
|
+
4. **Nunca** fazer todos os upgrades de uma vez
|
|
148
|
+
5. **Preferir** ordem: bun -> tailwind -> react -> next
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
[Voltar ao README](../README.md) | [create](./create.md) | [analyze](./analyze.md) | [migrate](./migrate.md)
|
package/package.json
CHANGED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import * as p from "@clack/prompts"
|
|
2
|
+
import pc from "picocolors"
|
|
3
|
+
import { existsSync } from "node:fs"
|
|
4
|
+
import { join } from "node:path"
|
|
5
|
+
|
|
6
|
+
const LOLA_DIR = join(process.env.HOME || "~", ".lola")
|
|
7
|
+
const LOLA_REPO = "git@github.com:nimbuslab/lola.git"
|
|
8
|
+
const USER_MEMORY = join(process.env.HOME || "~", ".claude", "USER_MEMORY.md")
|
|
9
|
+
|
|
10
|
+
async function installLola(): Promise<void> {
|
|
11
|
+
console.log()
|
|
12
|
+
console.log(pc.cyan(" Lola - Code Agent da nimbuslab"))
|
|
13
|
+
console.log(pc.dim(" ==============================="))
|
|
14
|
+
console.log()
|
|
15
|
+
|
|
16
|
+
const isUpdate = existsSync(LOLA_DIR)
|
|
17
|
+
|
|
18
|
+
if (isUpdate) {
|
|
19
|
+
console.log(pc.dim(` Lola ja instalada em ${LOLA_DIR}`))
|
|
20
|
+
console.log(pc.cyan(" Atualizando..."))
|
|
21
|
+
|
|
22
|
+
const result = Bun.spawnSync(["git", "pull", "--quiet"], {
|
|
23
|
+
cwd: LOLA_DIR,
|
|
24
|
+
stdout: "inherit",
|
|
25
|
+
stderr: "inherit",
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
if (result.exitCode !== 0) {
|
|
29
|
+
console.log(pc.red(" Erro ao atualizar Lola"))
|
|
30
|
+
process.exit(1)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.log(pc.green(" Atualizado!"))
|
|
34
|
+
} else {
|
|
35
|
+
console.log(pc.cyan(` Instalando Lola em ${LOLA_DIR}...`))
|
|
36
|
+
|
|
37
|
+
const result = Bun.spawnSync(["git", "clone", "--quiet", LOLA_REPO, LOLA_DIR], {
|
|
38
|
+
stdout: "inherit",
|
|
39
|
+
stderr: "inherit",
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
if (result.exitCode !== 0) {
|
|
43
|
+
console.log(pc.red(" Erro ao clonar repositorio"))
|
|
44
|
+
console.log(pc.dim(" Verifique se tem acesso ao repo nimbuslab/lola"))
|
|
45
|
+
process.exit(1)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log(pc.green(" Instalado!"))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Verificar USER_MEMORY.md
|
|
52
|
+
const claudeDir = join(process.env.HOME || "~", ".claude")
|
|
53
|
+
if (!existsSync(USER_MEMORY)) {
|
|
54
|
+
console.log()
|
|
55
|
+
console.log(pc.cyan(" Criando USER_MEMORY.md..."))
|
|
56
|
+
|
|
57
|
+
await Bun.$`mkdir -p ${claudeDir}`
|
|
58
|
+
|
|
59
|
+
const content = `# User Memory
|
|
60
|
+
|
|
61
|
+
Memoria persistente para sessoes Claude Code
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Configuracoes da Lola
|
|
66
|
+
|
|
67
|
+
\`\`\`
|
|
68
|
+
lola_profile: millennial
|
|
69
|
+
\`\`\`
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Ultima Sessao
|
|
74
|
+
|
|
75
|
+
(sera preenchido automaticamente)
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
`
|
|
79
|
+
await Bun.write(USER_MEMORY, content)
|
|
80
|
+
console.log(pc.green(" USER_MEMORY.md criado!"))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
console.log()
|
|
84
|
+
console.log(pc.green(" Instalacao concluida!"))
|
|
85
|
+
console.log()
|
|
86
|
+
console.log(pc.bold(" Para usar a Lola:"))
|
|
87
|
+
console.log(pc.dim(" lola ") + pc.white("# Iniciar sessao"))
|
|
88
|
+
console.log(pc.dim(" lola suggest \"x\" ") + pc.white("# Sugerir melhoria"))
|
|
89
|
+
console.log()
|
|
90
|
+
console.log(pc.bold(" Para mudar perfil, edite ~/.claude/USER_MEMORY.md:"))
|
|
91
|
+
console.log(pc.dim(" lola_profile: millennial|genz|profissional|nerd|chill"))
|
|
92
|
+
console.log()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function suggestImprovement(message: string): Promise<void> {
|
|
96
|
+
if (!message) {
|
|
97
|
+
console.log(pc.red(" Erro: forneça uma mensagem"))
|
|
98
|
+
console.log(pc.dim(" Uso: nimbus lola suggest \"sua sugestao aqui\""))
|
|
99
|
+
process.exit(1)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Verificar gh cli
|
|
103
|
+
const ghCheck = Bun.spawnSync(["which", "gh"])
|
|
104
|
+
if (ghCheck.exitCode !== 0) {
|
|
105
|
+
console.log(pc.red(" Erro: GitHub CLI (gh) nao encontrado"))
|
|
106
|
+
console.log(pc.dim(" Instale: https://cli.github.com"))
|
|
107
|
+
process.exit(1)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Verificar autenticacao
|
|
111
|
+
const authCheck = Bun.spawnSync(["gh", "auth", "status"], {
|
|
112
|
+
stdout: "pipe",
|
|
113
|
+
stderr: "pipe",
|
|
114
|
+
})
|
|
115
|
+
if (authCheck.exitCode !== 0) {
|
|
116
|
+
console.log(pc.red(" Erro: GitHub CLI nao autenticado"))
|
|
117
|
+
console.log(pc.dim(" Execute: gh auth login"))
|
|
118
|
+
process.exit(1)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Pegar info do usuario
|
|
122
|
+
const gitUser = Bun.spawnSync(["git", "config", "user.name"], { stdout: "pipe" })
|
|
123
|
+
const gitEmail = Bun.spawnSync(["git", "config", "user.email"], { stdout: "pipe" })
|
|
124
|
+
|
|
125
|
+
const userName = gitUser.stdout.toString().trim() || "Dev"
|
|
126
|
+
const userEmail = gitEmail.stdout.toString().trim() || ""
|
|
127
|
+
|
|
128
|
+
console.log()
|
|
129
|
+
console.log(pc.cyan(" Criando sugestao..."))
|
|
130
|
+
|
|
131
|
+
const date = new Date().toISOString().split("T")[0]
|
|
132
|
+
const body = `## Sugestao
|
|
133
|
+
|
|
134
|
+
${message}
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
**Enviado por:** ${userName}
|
|
139
|
+
**Email:** ${userEmail}
|
|
140
|
+
**Data:** ${date}
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
*Criado via \`nimbus lola suggest\`*`
|
|
144
|
+
|
|
145
|
+
const title = `Sugestao: ${message.slice(0, 50)}${message.length > 50 ? "..." : ""}`
|
|
146
|
+
|
|
147
|
+
const result = Bun.spawnSync([
|
|
148
|
+
"gh", "issue", "create",
|
|
149
|
+
"--repo", "nimbuslab/lola",
|
|
150
|
+
"--title", title,
|
|
151
|
+
"--body", body,
|
|
152
|
+
"--label", "sugestao",
|
|
153
|
+
], {
|
|
154
|
+
stdout: "inherit",
|
|
155
|
+
stderr: "inherit",
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
if (result.exitCode !== 0) {
|
|
159
|
+
console.log(pc.red(" Erro ao criar issue"))
|
|
160
|
+
process.exit(1)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
console.log()
|
|
164
|
+
console.log(pc.green(" Sugestao enviada! Hugo vai revisar."))
|
|
165
|
+
console.log()
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export async function lola(args: string[]) {
|
|
169
|
+
const subcommand = args[0]
|
|
170
|
+
|
|
171
|
+
if (!subcommand || subcommand === "install" || subcommand === "sync") {
|
|
172
|
+
await installLola()
|
|
173
|
+
} else if (subcommand === "suggest") {
|
|
174
|
+
const message = args.slice(1).join(" ")
|
|
175
|
+
await suggestImprovement(message)
|
|
176
|
+
} else if (subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
|
|
177
|
+
showLolaHelp()
|
|
178
|
+
} else {
|
|
179
|
+
console.log(pc.red(` Subcomando desconhecido: ${subcommand}`))
|
|
180
|
+
showLolaHelp()
|
|
181
|
+
process.exit(1)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function showLolaHelp() {
|
|
186
|
+
console.log()
|
|
187
|
+
console.log(pc.bold(" Lola - Code Agent da nimbuslab"))
|
|
188
|
+
console.log()
|
|
189
|
+
console.log(pc.bold(" Uso:") + " nimbus lola [subcomando]")
|
|
190
|
+
console.log()
|
|
191
|
+
console.log(pc.bold(" Subcomandos:"))
|
|
192
|
+
console.log(pc.dim(" install ") + pc.white("Instalar/atualizar Lola"))
|
|
193
|
+
console.log(pc.dim(" sync ") + pc.white("Alias para install"))
|
|
194
|
+
console.log(pc.dim(" suggest \"msg\" ") + pc.white("Sugerir melhoria (cria issue)"))
|
|
195
|
+
console.log(pc.dim(" help ") + pc.white("Mostrar esta ajuda"))
|
|
196
|
+
console.log()
|
|
197
|
+
console.log(pc.bold(" Exemplos:"))
|
|
198
|
+
console.log(pc.dim(" $ nimbus lola install"))
|
|
199
|
+
console.log(pc.dim(" $ nimbus lola suggest \"adicionar suporte a X\""))
|
|
200
|
+
console.log()
|
|
201
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -5,9 +5,13 @@ import pc from "picocolors"
|
|
|
5
5
|
import { create } from "./commands/create"
|
|
6
6
|
import { analyze } from "./commands/analyze"
|
|
7
7
|
import { upgrade } from "./commands/upgrade"
|
|
8
|
+
import { lola } from "./commands/lola"
|
|
8
9
|
|
|
9
10
|
const PACKAGE_NAME = "@nimbuslab/cli"
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
// Lê versão do package.json em runtime
|
|
13
|
+
const pkg = await import("../package.json")
|
|
14
|
+
const CURRENT_VERSION = pkg.version
|
|
11
15
|
|
|
12
16
|
const LOGO = `
|
|
13
17
|
███╗ ██╗██╗███╗ ███╗██████╗ ██╗ ██╗███████╗
|
|
@@ -80,6 +84,8 @@ async function main() {
|
|
|
80
84
|
await analyze(args.slice(1))
|
|
81
85
|
} else if (command === "upgrade") {
|
|
82
86
|
await upgrade(args.slice(1))
|
|
87
|
+
} else if (command === "lola") {
|
|
88
|
+
await lola(args.slice(1))
|
|
83
89
|
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
84
90
|
showHelp()
|
|
85
91
|
} else if (command === "version" || command === "--version" || command === "-v") {
|
|
@@ -99,6 +105,7 @@ ${pc.bold("Commands:")}
|
|
|
99
105
|
create [name] Create a new project
|
|
100
106
|
analyze [dir] Analyze project stack
|
|
101
107
|
upgrade [target] Upgrade dependencies
|
|
108
|
+
lola [action] Lola - Code Agent
|
|
102
109
|
help Show this help
|
|
103
110
|
version Show version
|
|
104
111
|
|
|
@@ -120,11 +127,17 @@ ${pc.bold("Options:")}
|
|
|
120
127
|
--no-install Don't install dependencies
|
|
121
128
|
--template <url> Use custom template
|
|
122
129
|
|
|
130
|
+
${pc.bold("Lola (Code Agent):")}
|
|
131
|
+
lola install Install/update Lola
|
|
132
|
+
lola suggest Suggest improvement (creates issue)
|
|
133
|
+
|
|
123
134
|
${pc.bold("Examples:")}
|
|
124
135
|
${pc.dim("$")} nimbus create my-landing --landing
|
|
125
136
|
${pc.dim("$")} nimbus create my-app --app
|
|
126
137
|
${pc.dim("$")} nimbus analyze ./my-project
|
|
127
138
|
${pc.dim("$")} nimbus upgrade --plan
|
|
139
|
+
${pc.dim("$")} nimbus lola install
|
|
140
|
+
${pc.dim("$")} nimbus lola suggest "add support for X"
|
|
128
141
|
`)
|
|
129
142
|
}
|
|
130
143
|
|