cleudocode-core 1.0.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.
@@ -0,0 +1,581 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Cleudocode Core CLI
5
+ *
6
+ * Framework de orquestração de agentes AI para desenvolvimento
7
+ * Instalação rápida, configuração automática e integração com múltiplos LLMs
8
+ *
9
+ * @author Cleudocode Team
10
+ * @version 1.0.0
11
+ */
12
+
13
+ import { fileURLToPath } from 'node:url'
14
+ import { dirname, join } from 'node:path'
15
+ import { Command } from 'commander'
16
+ import chalk from 'chalk'
17
+ import ora from 'ora'
18
+ import { execa } from 'execa'
19
+ import fs from 'fs-extra'
20
+ import yaml from 'js-yaml'
21
+ import semver from 'semver'
22
+ import * as p from '@clack/prompts'
23
+
24
+ const __filename = fileURLToPath(import.meta.url)
25
+ const __dirname = dirname(__filename)
26
+ const PROJECT_ROOT = process.cwd()
27
+
28
+ // Versão atual
29
+ const pkg = JSON.parse(
30
+ fs.readFileSync(join(__dirname, '../package.json'), 'utf-8')
31
+ )
32
+ const VERSION = pkg.version
33
+
34
+ // Programa principal
35
+ const program = new Command()
36
+
37
+ program
38
+ .name('cleudocode-core')
39
+ .description('Cleudocode Core - AI Orchestration Framework')
40
+ .version(VERSION)
41
+
42
+ // =============================================================================
43
+ // COMANDO: init
44
+ // =============================================================================
45
+ program
46
+ .command('init')
47
+ .description('Inicializa Cleudocode Core no projeto atual')
48
+ .option('-f, --force', 'Forçar inicialização mesmo se já existir')
49
+ .option('-t, --template <tipo>', 'Template a usar (fullstack|frontend|backend|cli)', 'fullstack')
50
+ .action(async (options) => {
51
+ p.intro(chalk.bgGreen.black(' Cleudocode Core - Inicialização '))
52
+
53
+ const configPath = join(PROJECT_ROOT, '.cleudocode-core')
54
+
55
+ if (fs.existsSync(configPath) && !options.force) {
56
+ p.log.warn('Arquivo .cleudocode-core já existe!')
57
+ const shouldContinue = await p.confirm({
58
+ message: 'Deseja sobrescrever?',
59
+ initialValue: false
60
+ })
61
+
62
+ if (p.isCancel(shouldContinue) || !shouldContinue) {
63
+ p.cancel('Operação cancelada.')
64
+ return
65
+ }
66
+ }
67
+
68
+ const spinner = ora('Criando configuração...').start()
69
+
70
+ try {
71
+ // Copiar template de configuração
72
+ const templatePath = join(__dirname, '../templates/.cleudocode-core')
73
+ let configContent
74
+
75
+ if (fs.existsSync(templatePath)) {
76
+ configContent = fs.readFileSync(templatePath, 'utf-8')
77
+ } else {
78
+ // Configuração padrão inline
79
+ configContent = getDefaultConfig(options.template)
80
+ }
81
+
82
+ fs.writeFileSync(configPath, configContent)
83
+ spinner.succeed('Configuração criada com sucesso!')
84
+
85
+ // Criar estrutura de diretórios
86
+ const dirs = [
87
+ '.agents/agents',
88
+ '.agents/rules',
89
+ '.agents/tasks',
90
+ '.agents/templates',
91
+ '.agents/outputs',
92
+ '.agents/logs',
93
+ '.agents/storage'
94
+ ]
95
+
96
+ for (const dir of dirs) {
97
+ const fullPath = join(PROJECT_ROOT, dir)
98
+ if (!fs.existsSync(fullPath)) {
99
+ fs.ensureDirSync(fullPath)
100
+ }
101
+ }
102
+
103
+ p.log.success('Estrutura de diretórios criada!')
104
+
105
+ // Criar AGENTS.md
106
+ const agentsPath = join(PROJECT_ROOT, 'AGENTS.md')
107
+ if (!fs.existsSync(agentsPath)) {
108
+ fs.writeFileSync(agentsPath, getDefaultAgentsMd())
109
+ p.log.success('AGENTS.md criado!')
110
+ }
111
+
112
+ // Criar .env.example
113
+ const envExamplePath = join(PROJECT_ROOT, '.env.example')
114
+ if (!fs.existsSync(envExamplePath)) {
115
+ fs.writeFileSync(envExamplePath, getDefaultEnvExample())
116
+ p.log.success('.env.example criado!')
117
+ }
118
+
119
+ p.outro(chalk.green('✨ Cleudocode Core inicializado com sucesso!'))
120
+
121
+ console.log(`
122
+ ${chalk.bold('Próximos passos:')}
123
+
124
+ 1. Copie o arquivo de exemplo:
125
+ ${chalk.cyan('cp .env.example .env')}
126
+
127
+ 2. Edite .env e configure suas chaves de API
128
+
129
+ 3. Inicie o Ollama (se usar modelos locais):
130
+ ${chalk.cyan('ollama serve')}
131
+
132
+ 4. Execute seu primeiro comando:
133
+ ${chalk.cyan('npx cleudocode-core help')}
134
+
135
+ ${chalk.dim('Documentação: https://github.com/cleudocode/cleudocode-core')}
136
+ `)
137
+
138
+ } catch (error) {
139
+ spinner.fail('Erro ao inicializar')
140
+ p.log.error(error.message)
141
+ process.exit(1)
142
+ }
143
+ })
144
+
145
+ // =============================================================================
146
+ // COMANDO: install
147
+ // =============================================================================
148
+ program
149
+ .command('install')
150
+ .description('Instala Cleudocode Core globalmente')
151
+ .action(async () => {
152
+ p.intro(chalk.bgGreen.black(' Cleudocode Core - Instalação '))
153
+
154
+ const spinner = ora('Instalando cleudocode-core...').start()
155
+
156
+ try {
157
+ await execa('npm', ['install', '-g', 'cleudocode-core'], {
158
+ stdio: 'pipe'
159
+ })
160
+
161
+ spinner.succeed('cleudocode-core instalado globalmente!')
162
+
163
+ p.outro(chalk.green(`
164
+ ✨ Instalação concluída!
165
+
166
+ Use em qualquer projeto:
167
+ ${chalk.cyan('cleudocode-core init')}
168
+
169
+ Ou use sem instalar:
170
+ ${chalk.cyan('npx cleudocode-core init')}
171
+ `))
172
+
173
+ } catch (error) {
174
+ spinner.fail('Erro na instalação')
175
+ p.log.error(error.message)
176
+ process.exit(1)
177
+ }
178
+ })
179
+
180
+ // =============================================================================
181
+ // COMANDO: config
182
+ // =============================================================================
183
+ program
184
+ .command('config')
185
+ .description('Mostra ou edita configuração')
186
+ .argument('[chave]', 'Chave de configuração')
187
+ .option('-e, --edit', 'Editar configuração')
188
+ .option('-v, --value <valor>', 'Definir valor')
189
+ .action(async (key, options) => {
190
+ const configPath = join(PROJECT_ROOT, '.cleudocode-core')
191
+
192
+ if (!fs.existsSync(configPath)) {
193
+ p.log.error('Configuração não encontrada. Execute: cleudocode-core init')
194
+ process.exit(1)
195
+ }
196
+
197
+ const config = yaml.load(fs.readFileSync(configPath, 'utf-8'))
198
+
199
+ if (options.edit) {
200
+ const editor = process.env.EDITOR || 'nano'
201
+ await execa(editor, [configPath], { stdio: 'inherit' })
202
+ p.log.success('Configuração atualizada!')
203
+ return
204
+ }
205
+
206
+ if (key) {
207
+ const keys = key.split('.')
208
+ let value = config
209
+ for (const k of keys) {
210
+ value = value?.[k]
211
+ }
212
+
213
+ if (value !== undefined) {
214
+ console.log(JSON.stringify(value, null, 2))
215
+ } else {
216
+ p.log.error(`Chave "${key}" não encontrada`)
217
+ }
218
+ } else {
219
+ console.log(yaml.dump(config))
220
+ }
221
+ })
222
+
223
+ // =============================================================================
224
+ // COMANDO: agents
225
+ // =============================================================================
226
+ program
227
+ .command('agents')
228
+ .description('Lista ou gerencia agentes')
229
+ .option('-l, --list', 'Listar agentes disponíveis')
230
+ .option('-a, --add <nome>', 'Adicionar novo agente')
231
+ .option('-r, --remove <nome>', 'Remover agente')
232
+ .action(async (options) => {
233
+ const agentsDir = join(PROJECT_ROOT, '.agents/agents')
234
+
235
+ if (options.list || !options.add && !options.remove) {
236
+ if (!fs.existsSync(agentsDir)) {
237
+ p.log.warn('Diretório de agentes não encontrado. Execute: cleudocode-core init')
238
+ return
239
+ }
240
+
241
+ const files = fs.readdirSync(agentsDir)
242
+ const agents = files
243
+ .filter(f => f.endsWith('.md'))
244
+ .map(f => f.replace('.md', ''))
245
+
246
+ if (agents.length === 0) {
247
+ p.log.info('Nenhum agente encontrado')
248
+ return
249
+ }
250
+
251
+ console.log(chalk.bold('\nAgentes disponíveis:\n'))
252
+ agents.forEach(agent => {
253
+ console.log(` ${chalk.cyan('•')} ${agent}`)
254
+ })
255
+ console.log()
256
+ }
257
+
258
+ if (options.add) {
259
+ const agentPath = join(agentsDir, `${options.add}.md`)
260
+ if (fs.existsSync(agentPath)) {
261
+ p.log.error(`Agente "${options.add}" já existe`)
262
+ return
263
+ }
264
+
265
+ const template = getAgentTemplate(options.add)
266
+ fs.writeFileSync(agentPath, template)
267
+ p.log.success(`Agente "${options.add}" criado em ${agentPath}`)
268
+ }
269
+
270
+ if (options.remove) {
271
+ const agentPath = join(agentsDir, `${options.remove}.md`)
272
+ if (!fs.existsSync(agentPath)) {
273
+ p.log.error(`Agente "${options.remove}" não encontrado`)
274
+ return
275
+ }
276
+
277
+ fs.unlinkSync(agentPath)
278
+ p.log.success(`Agente "${options.remove}" removido`)
279
+ }
280
+ })
281
+
282
+ // =============================================================================
283
+ // COMANDO: doctor
284
+ // =============================================================================
285
+ program
286
+ .command('doctor')
287
+ .description('Verifica saúde da instalação')
288
+ .action(async () => {
289
+ p.intro(chalk.bgGreen.black(' Cleudocode Core - Doctor '))
290
+
291
+ const checks = []
292
+
293
+ // Verificar Node.js
294
+ const nodeVersion = process.version
295
+ const minVersion = 'v18.0.0'
296
+ checks.push({
297
+ name: 'Node.js',
298
+ status: semver.gte(nodeVersion, minVersion) ? 'ok' : 'error',
299
+ message: `${nodeVersion} (mínimo: ${minVersion})`
300
+ })
301
+
302
+ // Verificar .cleudocode-core
303
+ const configPath = join(PROJECT_ROOT, '.cleudocode-core')
304
+ checks.push({
305
+ name: '.cleudocode-core',
306
+ status: fs.existsSync(configPath) ? 'ok' : 'warn',
307
+ message: fs.existsSync(configPath) ? 'Encontrado' : 'Não encontrado (execute: cleudocode-core init)'
308
+ })
309
+
310
+ // Verificar AGENTS.md
311
+ const agentsPath = join(PROJECT_ROOT, 'AGENTS.md')
312
+ checks.push({
313
+ name: 'AGENTS.md',
314
+ status: fs.existsSync(agentsPath) ? 'ok' : 'warn',
315
+ message: fs.existsSync(agentsPath) ? 'Encontrado' : 'Não encontrado'
316
+ })
317
+
318
+ // Verificar .env
319
+ const envPath = join(PROJECT_ROOT, '.env')
320
+ checks.push({
321
+ name: '.env',
322
+ status: fs.existsSync(envPath) ? 'ok' : 'info',
323
+ message: fs.existsSync(envPath) ? 'Encontrado' : 'Opcional (copie de .env.example)'
324
+ })
325
+
326
+ // Verificar Ollama
327
+ try {
328
+ await execa('ollama', ['--version'])
329
+ checks.push({
330
+ name: 'Ollama',
331
+ status: 'ok',
332
+ message: 'Instalado'
333
+ })
334
+ } catch {
335
+ checks.push({
336
+ name: 'Ollama',
337
+ status: 'info',
338
+ message: 'Não instalado (opcional para modelos locais)'
339
+ })
340
+ }
341
+
342
+ // Exibir resultados
343
+ console.log()
344
+ for (const check of checks) {
345
+ const icon = {
346
+ ok: chalk.green('✓'),
347
+ warn: chalk.yellow('⚠'),
348
+ error: chalk.red('✗'),
349
+ info: chalk.blue('ℹ')
350
+ }[check.status]
351
+
352
+ console.log(`${icon} ${chalk.bold(check.name)}: ${check.message}`)
353
+ }
354
+ console.log()
355
+
356
+ const hasError = checks.some(c => c.status === 'error')
357
+ const hasWarn = checks.some(c => c.status === 'warn')
358
+
359
+ if (hasError) {
360
+ p.outro(chalk.red('Foram encontrados erros que precisam de atenção'))
361
+ } else if (hasWarn) {
362
+ p.outro(chalk.yellow('Tudo ok, mas há avisos para melhorar a experiência'))
363
+ } else {
364
+ p.outro(chalk.green('Tudo certo! Configuração está saudável'))
365
+ }
366
+ })
367
+
368
+ // =============================================================================
369
+ // COMANDO: run
370
+ // =============================================================================
371
+ program
372
+ .command('run <agente>')
373
+ .description('Executa um agente')
374
+ .option('-t, --task <tarefa>', 'Tarefa a executar')
375
+ .option('-v, --verbose', 'Modo verbose')
376
+ .action(async (agent, options) => {
377
+ p.intro(chalk.bgGreen.black(` Cleudocode Core - ${agent} `))
378
+
379
+ const agentPath = join(PROJECT_ROOT, '.agents/agents', `${agent}.md`)
380
+
381
+ if (!fs.existsSync(agentPath)) {
382
+ p.log.error(`Agente "${agent}" não encontrado`)
383
+ p.log.info('Use "cleudocode-core agents --list" para ver agentes disponíveis')
384
+ process.exit(1)
385
+ }
386
+
387
+ const agentContent = fs.readFileSync(agentPath, 'utf-8')
388
+
389
+ if (options.task) {
390
+ p.log.info(`Executando tarefa: ${options.task}`)
391
+ // Implementar execução de tarefa
392
+ console.log(chalk.dim('(Funcionalidade em desenvolvimento)'))
393
+ } else {
394
+ console.log(agentContent)
395
+ }
396
+ })
397
+
398
+ // =============================================================================
399
+ // COMANDO: update
400
+ // =============================================================================
401
+ program
402
+ .command('update')
403
+ .description('Atualiza cleudocode-core para última versão')
404
+ .option('-g, --global', 'Atualizar instalação global')
405
+ .action(async (options) => {
406
+ const spinner = ora('Verificando atualizações...').start()
407
+
408
+ try {
409
+ const { stdout } = await execa('npm', ['view', 'cleudocode-core', 'version'])
410
+ const latestVersion = stdout.trim()
411
+
412
+ if (semver.gt(latestVersion, VERSION)) {
413
+ spinner.info(`Nova versão disponível: ${latestVersion} (atual: ${VERSION})`)
414
+
415
+ if (options.global) {
416
+ const updateSpinner = ora('Atualizando instalação global...').start()
417
+ await execa('npm', ['update', '-g', 'cleudocode-core'])
418
+ updateSpinner.succeed('Atualizado com sucesso!')
419
+ } else {
420
+ console.log(`
421
+ Para atualizar:
422
+
423
+ ${chalk.cyan('Global:')}
424
+ npm update -g cleudocode-core
425
+
426
+ ${chalk.cyan('Local (projeto):')}
427
+ npm update cleudocode-core
428
+
429
+ ${chalk.cyan('Usando npx (sempre mais recente):')}
430
+ npx cleudocode-core@latest
431
+ `)
432
+ }
433
+ } else {
434
+ spinner.succeed('Você já está na versão mais recente!')
435
+ }
436
+ } catch (error) {
437
+ spinner.fail('Erro ao verificar atualizações')
438
+ p.log.error(error.message)
439
+ }
440
+ })
441
+
442
+ // =============================================================================
443
+ // COMANDO: templates
444
+ // =============================================================================
445
+ program
446
+ .command('templates')
447
+ .description('Lista templates disponíveis')
448
+ .action(async () => {
449
+ const templatesDir = join(__dirname, '../templates')
450
+
451
+ if (!fs.existsSync(templatesDir)) {
452
+ p.log.warn('Nenhum template encontrado')
453
+ return
454
+ }
455
+
456
+ const templates = fs.readdirSync(templatesDir)
457
+
458
+ console.log(chalk.bold('\nTemplates disponíveis:\n'))
459
+ templates.forEach(t => {
460
+ console.log(` ${chalk.cyan('•')} ${t}`)
461
+ })
462
+ console.log()
463
+ })
464
+
465
+ // =============================================================================
466
+ // HELP PERSONALIZADO
467
+ // =============================================================================
468
+ program.addHelpText('after', `
469
+ ${chalk.bold('Exemplos:')}
470
+ ${chalk.cyan('npx cleudocode-core init')} Inicializa no projeto atual
471
+ ${chalk.cyan('cleudocode-core install')} Instala globalmente
472
+ ${chalk.cyan('cleudocode-core agents --list')} Lista agentes
473
+ ${chalk.cyan('cleudocode-core doctor')} Verifica saúde da instalação
474
+ ${chalk.cyan('cleudocode-core config settings')} Mostra configurações
475
+ ${chalk.cyan('cleudocode-core run dev -t "criar API"')} Executa agente
476
+
477
+ ${chalk.bold('Links:')}
478
+ Documentação: https://github.com/cleudocode/cleudocode-core
479
+ Issues: https://github.com/cleudocode/cleudocode-core/issues
480
+ NPM: https://www.npmjs.com/package/cleudocode-core
481
+ `)
482
+
483
+ // =============================================================================
484
+ // EXECUÇÃO
485
+ // =============================================================================
486
+ program.parse()
487
+
488
+ // =============================================================================
489
+ // FUNÇÕES AUXILIARES
490
+ // =============================================================================
491
+
492
+ function getDefaultConfig(template) {
493
+ return `# Cleudocode Core Configuration
494
+ # Template: ${template}
495
+ # Gerado em: ${new Date().toISOString()}
496
+
497
+ version: "1.0.0"
498
+
499
+ settings:
500
+ language: "pt-BR"
501
+ default_agent: "general-purpose"
502
+ verbose: false
503
+ log_mode: "console"
504
+
505
+ llms:
506
+ models:
507
+ - name: "qwen3:4b"
508
+ backend: "ollama"
509
+ hostname: "http://localhost:11434"
510
+ enabled: true
511
+
512
+ agents:
513
+ enabled:
514
+ - "general-purpose"
515
+ - "code-review"
516
+ - "testing"
517
+ default: "general-purpose"
518
+
519
+ paths:
520
+ rules: ".agents/rules"
521
+ agents: ".agents/agents"
522
+ tasks: ".agents/tasks"
523
+ templates: ".agents/templates"
524
+ `
525
+ }
526
+
527
+ function getDefaultAgentsMd() {
528
+ return `# AGENTS.md - Cleudocode Hub
529
+
530
+ ## Agentes Disponíveis
531
+
532
+ | Agente | Descrição |
533
+ |--------|-----------|
534
+ | @general-purpose | Agente de uso geral |
535
+ | @code-review | Revisão de código |
536
+ | @testing | Criação de testes |
537
+
538
+ ## Uso
539
+
540
+ \`\`\`bash
541
+ # Listar agentes
542
+ cleudocode-core agents --list
543
+
544
+ # Executar agente
545
+ cleudocode-core run general-purpose -t "minha tarefa"
546
+ \`\`\`
547
+ `
548
+ }
549
+
550
+ function getDefaultEnvExample() {
551
+ return `# Cleudocode Hub - Environment Variables
552
+ # Copie para .env e preencha com suas credenciais
553
+
554
+ # API Keys
555
+ OPENAI_API_KEY=sk-...
556
+ ANTHROPIC_API_KEY=sk-ant-...
557
+ GEMINI_API_KEY=...
558
+
559
+ # Ollama (Local)
560
+ OLLAMA_HOST=http://localhost:11434
561
+ OLLAMA_MODEL=qwen3:4b
562
+ `
563
+ }
564
+
565
+ function getAgentTemplate(name) {
566
+ return `# ${name.toUpperCase()}
567
+
568
+ ## Descrição
569
+ Agente especializado em ${name}.
570
+
571
+ ## Comandos
572
+ - *help - Mostrar ajuda
573
+ - *status - Status atual
574
+ - *exit - Sair do modo agente
575
+
576
+ ## Exemplo de Uso
577
+ \`\`\`bash
578
+ cleudocode-core run ${name} -t "descrição da tarefa"
579
+ \`\`\`
580
+ `
581
+ }
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "cleudocode-core",
3
+ "version": "1.0.0",
4
+ "description": "Cleudocode Core - AI Orchestration Framework para desenvolvimento com agentes AI",
5
+ "author": "Cleudocode Team",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "ai",
9
+ "agents",
10
+ "orchestrator",
11
+ "cleudocode",
12
+ "cli",
13
+ "automation",
14
+ "development",
15
+ "llm"
16
+ ],
17
+ "type": "module",
18
+ "main": "src/index.js",
19
+ "bin": {
20
+ "cleudocode": "./bin/cleudocode.js",
21
+ "cleudocode-core": "./bin/cleudocode.js",
22
+ "ccore": "./bin/cleudocode.js"
23
+ },
24
+ "files": [
25
+ "bin/",
26
+ "src/",
27
+ "templates/",
28
+ ".cleudocode-core",
29
+ "AGENTS.md",
30
+ "README.md"
31
+ ],
32
+ "scripts": {
33
+ "start": "node bin/cleudocode.js",
34
+ "dev": "node --watch bin/cleudocode.js",
35
+ "test": "node --test tests/**/*.test.js",
36
+ "lint": "eslint .",
37
+ "format": "prettier --write ."
38
+ },
39
+ "dependencies": {
40
+ "@clack/prompts": "^0.11.0",
41
+ "chalk": "^5.4.1",
42
+ "commander": "^13.1.0",
43
+ "execa": "^9.5.2",
44
+ "fs-extra": "^11.3.0",
45
+ "js-yaml": "^4.1.0",
46
+ "ora": "^8.2.0",
47
+ "picocolors": "^1.1.1",
48
+ "semver": "^7.7.1"
49
+ },
50
+ "publishConfig": {
51
+ "registry": "https://registry.npmjs.org",
52
+ "access": "public"
53
+ },
54
+ "engines": {
55
+ "node": ">=18.0.0",
56
+ "npm": ">=9.0.0"
57
+ },
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "git+https://github.com/cleudocode/cleudocode-core.git"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/cleudocode/cleudocode-core/issues"
64
+ },
65
+ "homepage": "https://github.com/cleudocode/cleudocode-core#readme",
66
+ "lint-staged": {
67
+ "*.js": [
68
+ "eslint --fix",
69
+ "prettier --write"
70
+ ],
71
+ "*.{md,json,yaml,yml}": [
72
+ "prettier --write"
73
+ ]
74
+ }
75
+ }
package/src/index.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Cleudocode Core - Main Entry Point
3
+ *
4
+ * AI Orchestration Framework para desenvolvimento com agentes AI
5
+ *
6
+ * @module cleudocode-core
7
+ * @version 1.0.0
8
+ */
9
+
10
+ export { version } from '../package.json'
11
+
12
+ /**
13
+ * Inicializa o Cleudocode Core
14
+ * @returns {Object} Configuração inicializada
15
+ */
16
+ export function init() {
17
+ console.log('Cleudocode Core initialized')
18
+ return {
19
+ version: '1.0.0',
20
+ name: 'cleudocode-core'
21
+ }
22
+ }
23
+
24
+ export default { init }