@korl3one/ccode 2.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.
- package/README.md +329 -0
- package/dist/ai/claude.d.ts +10 -0
- package/dist/ai/claude.js +34 -0
- package/dist/ai/manager.d.ts +17 -0
- package/dist/ai/manager.js +41 -0
- package/dist/ai/ollama.d.ts +10 -0
- package/dist/ai/ollama.js +27 -0
- package/dist/ai/provider.d.ts +12 -0
- package/dist/ai/provider.js +1 -0
- package/dist/cli/brand.d.ts +27 -0
- package/dist/cli/brand.js +90 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +737 -0
- package/dist/cli/watcher.d.ts +31 -0
- package/dist/cli/watcher.js +90 -0
- package/dist/core/context.d.ts +26 -0
- package/dist/core/context.js +45 -0
- package/dist/core/prompt-builder.d.ts +38 -0
- package/dist/core/prompt-builder.js +250 -0
- package/dist/core/tasks.d.ts +35 -0
- package/dist/core/tasks.js +59 -0
- package/dist/utils/files.d.ts +12 -0
- package/dist/utils/files.js +34 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
```
|
|
2
|
+
██████╗ ██████╗ ██████╗ ██████╗ ███████╗
|
|
3
|
+
██╔════╝██╔════╝ ██╔═══██╗██╔══██╗██╔════╝
|
|
4
|
+
██║ ██║ ██║ ██║██║ ██║█████╗
|
|
5
|
+
██║ ██║ ██║ ██║██║ ██║██╔══╝
|
|
6
|
+
╚██████╗╚██████╗ ╚██████╔╝██████╔╝███████╗
|
|
7
|
+
╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
|
|
8
|
+
Context-Persistent AI Development v2.0
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# CCODE — Contexto Persistente para Desarrollo Asistido
|
|
14
|
+
|
|
15
|
+
## QUE es CCODE
|
|
16
|
+
|
|
17
|
+
CCODE es una herramienta CLI que genera y mantiene el **contexto de trabajo** de un proyecto de software. Genera documentacion profesional, arquitectura, reglas de desarrollo y un checklist de tareas verificables — todo adaptado automaticamente a la complejidad real del proyecto.
|
|
18
|
+
|
|
19
|
+
**CCODE no genera codigo.** Genera el contexto que guia el desarrollo.
|
|
20
|
+
|
|
21
|
+
Cuando ejecutas `ccode init`, un wizard interactivo te pregunta sobre tu proyecto y una IA genera:
|
|
22
|
+
|
|
23
|
+
| Archivo | Contenido |
|
|
24
|
+
|---------|-----------|
|
|
25
|
+
| `project.md` | Vision, objetivos, alcance y funcionalidades |
|
|
26
|
+
| `architecture.md` | Estructura del sistema adaptada a la complejidad |
|
|
27
|
+
| `rules.md` | Estandares de desarrollo especificos al stack |
|
|
28
|
+
| `tasks.json` | Checklist de tareas con criterios de aceptacion |
|
|
29
|
+
| `state.json` | Tarea activa y etapa del workflow |
|
|
30
|
+
| `context.json` | Configuracion general del proyecto |
|
|
31
|
+
| `memory.md` | Historial de decisiones y tareas completadas |
|
|
32
|
+
| `config.json` | Configuracion del proveedor de IA |
|
|
33
|
+
|
|
34
|
+
Todo vive en la carpeta `.ccode/` dentro del repositorio. Cualquier desarrollador o IA puede leerla y entender el proyecto al instante.
|
|
35
|
+
|
|
36
|
+
### El principio fundamental
|
|
37
|
+
|
|
38
|
+
> **El contexto vive en el proyecto, no en la conversacion.**
|
|
39
|
+
|
|
40
|
+
Cuando trabajas con IA en un proyecto grande, el contexto se pierde al cambiar de sesion, modelo o herramienta. Cada vez hay que re-explicar todo. CCODE resuelve esto almacenando el contexto en el repositorio como archivos versionables con Git.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## COMO funciona
|
|
45
|
+
|
|
46
|
+
### Instalacion
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Clonar el repositorio
|
|
50
|
+
git clone https://github.com/iDevelop25/ccode.git
|
|
51
|
+
cd ccode
|
|
52
|
+
|
|
53
|
+
# Instalar dependencias
|
|
54
|
+
npm install
|
|
55
|
+
|
|
56
|
+
# Compilar
|
|
57
|
+
npm run build
|
|
58
|
+
|
|
59
|
+
# Vincular globalmente
|
|
60
|
+
npm link
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Flujo de trabajo
|
|
64
|
+
|
|
65
|
+
#### Paso 1: Inicializar el proyecto
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
cd mi-proyecto
|
|
69
|
+
ccode init
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
El wizard te guia paso a paso:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
●○○○ Paso 1/4 — Descripcion del proyecto
|
|
76
|
+
> "Una app de gestion de tareas con autenticacion y dashboard"
|
|
77
|
+
|
|
78
|
+
●●○○ Paso 2/4 — Funcionalidades principales
|
|
79
|
+
> "Login, registro, CRUD de tareas, filtros, estadisticas"
|
|
80
|
+
|
|
81
|
+
●●●○ Paso 3/4 — Stack tecnologico
|
|
82
|
+
> "Next.js, TypeScript, Prisma, PostgreSQL"
|
|
83
|
+
|
|
84
|
+
●●●● Paso 4/4 — Tipo de proyecto
|
|
85
|
+
> "Aplicacion web"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
La IA analiza la descripcion y decide automaticamente el nivel de complejidad:
|
|
89
|
+
|
|
90
|
+
- **Simple** (prototipo, pocas features): contexto ligero, 3-5 tareas
|
|
91
|
+
- **Medio** (app estandar): contexto moderado, 5-8 tareas
|
|
92
|
+
- **Complejo** (multiples modulos, integraciones): contexto completo con patrones y diagramas, 8-12 tareas
|
|
93
|
+
|
|
94
|
+
Un login simple no necesita diagramas de microservicios. CCODE es inteligente al respecto.
|
|
95
|
+
|
|
96
|
+
#### Paso 2: Sesion persistente
|
|
97
|
+
|
|
98
|
+
Despues de `init`, CCODE **no se cierra**. Entra en una sesion interactiva que se queda activa observando tu proyecto:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
████████████░░░░░░░░ 60% (3/5)
|
|
102
|
+
> Tarea activa: TASK-002 — Crear formulario de login
|
|
103
|
+
|
|
104
|
+
? Que hacemos?
|
|
105
|
+
> Verificar progreso (se detectaron cambios)
|
|
106
|
+
Marcar tarea como completada
|
|
107
|
+
Iniciar siguiente tarea (2 pendientes)
|
|
108
|
+
Generar / actualizar plan de tareas
|
|
109
|
+
Ver estado completo
|
|
110
|
+
Ver contexto generado
|
|
111
|
+
Salir
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
La sesion funciona como un loop continuo:
|
|
115
|
+
|
|
116
|
+
1. **Detecta cambios** en tus archivos automaticamente (FileWatcher)
|
|
117
|
+
2. **Muestra progreso** con barra visual y tarea activa
|
|
118
|
+
3. **Adapta el menu** al estado actual del proyecto
|
|
119
|
+
4. **Sugiere acciones** relevantes (si hay cambios + tarea activa → sugiere verificar)
|
|
120
|
+
5. **Se recupera de errores** — si algo falla, la sesion sigue activa
|
|
121
|
+
|
|
122
|
+
Tu desarrollas en tu editor favorito. CCODE esta en otra terminal como un acompanante que detecta tu progreso.
|
|
123
|
+
|
|
124
|
+
#### Paso 3: Verificacion automatica
|
|
125
|
+
|
|
126
|
+
Cuando CCODE detecta cambios en tus archivos, puedes pedirle que verifique:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
> Verificar progreso con IA
|
|
130
|
+
|
|
131
|
+
Verificando 5 tareas contra el estado del proyecto...
|
|
132
|
+
|
|
133
|
+
✓ TASK-001: Configurar proyecto base — COMPLETADA
|
|
134
|
+
Evidencia: package.json, tsconfig.json y estructura de carpetas encontrados
|
|
135
|
+
|
|
136
|
+
◐ TASK-002: Crear formulario de login — EN PROGRESO
|
|
137
|
+
Falta: Campo de contrasena no encontrado, validacion pendiente
|
|
138
|
+
|
|
139
|
+
○ TASK-003: Implementar autenticacion JWT — PENDIENTE
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
La IA compara los **criterios de aceptacion** de cada tarea con los **archivos reales** del proyecto. No adivina — verifica.
|
|
143
|
+
|
|
144
|
+
#### Acciones disponibles
|
|
145
|
+
|
|
146
|
+
| Accion | Que hace |
|
|
147
|
+
|--------|----------|
|
|
148
|
+
| **Conectar IA** | Configura Claude o Ollama como proveedor |
|
|
149
|
+
| **Siguiente tarea** | Muestra la tarea mas prioritaria y ofrece iniciarla |
|
|
150
|
+
| **Verificar progreso** | La IA escanea el proyecto y actualiza estados |
|
|
151
|
+
| **Completar tarea** | Marca como completada, registra en memoria |
|
|
152
|
+
| **Re-planificar** | Genera nuevas tareas considerando lo ya completado |
|
|
153
|
+
| **Ver estado** | Dashboard con barra de progreso y estadisticas |
|
|
154
|
+
| **Ver contexto** | Muestra cualquier archivo de `.ccode/` |
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## POR QUE CCODE
|
|
159
|
+
|
|
160
|
+
### El problema
|
|
161
|
+
|
|
162
|
+
El desarrollo asistido por IA tiene un problema critico: **el contexto es efimero**. Cada vez que cambias de sesion, modelo o herramienta, pierdes el contexto acumulado. El desarrollador termina re-explicando la arquitectura, las decisiones previas y el estado actual una y otra vez.
|
|
163
|
+
|
|
164
|
+
### La solucion
|
|
165
|
+
|
|
166
|
+
CCODE aplica el principio de **contexto persistente**: toda la informacion del proyecto se almacena como archivos dentro del repositorio. Esto significa:
|
|
167
|
+
|
|
168
|
+
- **Independencia de sesion:** El contexto no depende de la memoria de ninguna herramienta. Cierras CCODE, vuelves manana, y todo sigue ahi.
|
|
169
|
+
- **Independencia de modelo:** Cualquier IA (Claude, GPT, Ollama, la que sea) puede leer `.ccode/` y entender el proyecto al instante.
|
|
170
|
+
- **Trazabilidad:** Cada cambio queda en archivos versionables con Git. Puedes ver cuando se tomo cada decision.
|
|
171
|
+
- **Consistencia:** Todos los colaboradores y herramientas operan con la misma fuente de verdad.
|
|
172
|
+
- **Workflow explicito:** El estado del workflow evita que se ejecuten acciones fuera de orden.
|
|
173
|
+
|
|
174
|
+
### Por que contexto y no codigo
|
|
175
|
+
|
|
176
|
+
CCODE genera **que** construir, no **como** programarlo. Las tareas son un checklist descriptivo con criterios de aceptacion:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
Bueno: "Crear formulario de login con campos usuario y contrasena"
|
|
180
|
+
Malo: "Implementar const form = document.createElement('form')..."
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Esto permite que cualquier desarrollador (humano o IA) ejecute las tareas con su propio criterio tecnico. CCODE guia el rumbo, no dicta la implementacion.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## PARA QUE sirve CCODE
|
|
188
|
+
|
|
189
|
+
### Para el desarrollador
|
|
190
|
+
|
|
191
|
+
- **Elimina la perdida de contexto** entre sesiones de trabajo
|
|
192
|
+
- **Guia paso a paso** sin que te pierdas en un proyecto grande
|
|
193
|
+
- **Detecta tu progreso** automaticamente mientras programas
|
|
194
|
+
- **Adapta la complejidad** al tamano real del proyecto
|
|
195
|
+
|
|
196
|
+
### Para el equipo
|
|
197
|
+
|
|
198
|
+
- **Fuente de verdad unica:** Todos ven el mismo estado del proyecto
|
|
199
|
+
- **Onboarding rapido:** Un nuevo miembro lee `.ccode/` y entiende todo
|
|
200
|
+
- **Decisiones trazables:** El historial de memoria muestra por que se tomaron decisiones
|
|
201
|
+
|
|
202
|
+
### Para la IA
|
|
203
|
+
|
|
204
|
+
- **Contexto completo en un directorio:** Cualquier LLM puede leer `.ccode/` sin configuracion
|
|
205
|
+
- **Tareas verificables:** La IA puede confirmar objetivamente si una tarea esta completa
|
|
206
|
+
- **Arquitectura como referencia:** Las respuestas de la IA mantienen coherencia con la arquitectura definida
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Arquitectura del sistema
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
src/
|
|
214
|
+
cli/
|
|
215
|
+
index.ts → Entry point, sesion persistente, handlers de acciones
|
|
216
|
+
brand.ts → Identidad visual (logo ASCII, paleta, componentes UI)
|
|
217
|
+
watcher.ts → FileWatcher (observa cambios en tiempo real)
|
|
218
|
+
core/
|
|
219
|
+
context.ts → ContextEngine (configuracion + estado del workflow)
|
|
220
|
+
tasks.ts → TaskEngine (checklist de tareas con prioridades)
|
|
221
|
+
prompt-builder.ts → Meta-prompts adaptativos, generacion y verificacion
|
|
222
|
+
ai/
|
|
223
|
+
provider.ts → Interfaz comun IAIProvider (patron Adapter)
|
|
224
|
+
claude.ts → Adapter para Claude (API de Anthropic)
|
|
225
|
+
ollama.ts → Adapter para Ollama (modelos locales)
|
|
226
|
+
manager.ts → Gestion de configuracion y conexion
|
|
227
|
+
utils/
|
|
228
|
+
files.ts → Abstraccion del sistema de archivos
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Patrones de diseno
|
|
232
|
+
|
|
233
|
+
| Patron | Donde | Por que |
|
|
234
|
+
|--------|-------|---------|
|
|
235
|
+
| **Adapter** | `ai/` | Proveedores intercambiables sin cambiar el core |
|
|
236
|
+
| **State Machine** | `context.ts` | Workflow explicito (created → connected → planned → in_progress → idle) |
|
|
237
|
+
| **Observer** | `watcher.ts` | Deteccion reactiva de cambios en archivos |
|
|
238
|
+
| **Builder** | `prompt-builder.ts` | Construccion incremental de prompts complejos |
|
|
239
|
+
|
|
240
|
+
### Paleta de colores
|
|
241
|
+
|
|
242
|
+
| Color | Hex | Uso |
|
|
243
|
+
|-------|-----|-----|
|
|
244
|
+
| Primary | `#00B4D8` | Elementos principales, headers |
|
|
245
|
+
| Secondary | `#0077B6` | Acentos secundarios |
|
|
246
|
+
| Accent | `#90E0EF` | Highlights, info destacada |
|
|
247
|
+
| Success | `#2DC653` | Operaciones exitosas |
|
|
248
|
+
| Warning | `#FFB703` | Advertencias |
|
|
249
|
+
| Error | `#E63946` | Errores |
|
|
250
|
+
|
|
251
|
+
### Logo gradiente
|
|
252
|
+
|
|
253
|
+
El logo ASCII usa un gradiente de 6 tonos de azul/cyan:
|
|
254
|
+
`#90E0EF → #48CAE4 → #00B4D8 → #0096C7 → #0077B6 → #023E8A`
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Stack tecnologico
|
|
259
|
+
|
|
260
|
+
| Tecnologia | Rol |
|
|
261
|
+
|------------|-----|
|
|
262
|
+
| **Node.js** | Runtime |
|
|
263
|
+
| **TypeScript** | Tipado estatico, interfaces |
|
|
264
|
+
| **ESM** | Sistema de modulos (`"type": "module"`, `NodeNext`) |
|
|
265
|
+
| **Commander.js** | Definicion de comandos CLI |
|
|
266
|
+
| **Inquirer v13** | Prompts interactivos y menus |
|
|
267
|
+
| **Chalk v5** | Colores en terminal |
|
|
268
|
+
| **Ora v8** | Spinners de progreso |
|
|
269
|
+
| **Axios** | HTTP client para APIs de IA |
|
|
270
|
+
| **fs-extra** | Operaciones de archivos mejoradas |
|
|
271
|
+
| **Vitest** | Testing |
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Testing
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
# Ejecutar tests
|
|
279
|
+
npm test
|
|
280
|
+
|
|
281
|
+
# Tests en modo watch
|
|
282
|
+
npm test:watch
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
19 tests cubriendo:
|
|
286
|
+
- `PromptBuilder.parseJSON` — parsing robusto de respuestas de IA (directo, envuelto en texto, bloques markdown)
|
|
287
|
+
- `TaskEngine` — CRUD de tareas, priorizacion, estadisticas, manejo de errores
|
|
288
|
+
- `FileWatcher` — Estado inicial, flush, stop seguro
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Scripts disponibles
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
npm run build # Compilar TypeScript
|
|
296
|
+
npm run dev # Compilar en modo watch
|
|
297
|
+
npm start # Ejecutar CCODE
|
|
298
|
+
npm test # Ejecutar tests
|
|
299
|
+
npm run test:watch # Tests en modo watch
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Documentacion extendida
|
|
305
|
+
|
|
306
|
+
El proyecto incluye una guia de aprendizaje modular bajo la metodologia **QP2C** (Que, Como, Por que, Para que):
|
|
307
|
+
|
|
308
|
+
| Modulo | Tema |
|
|
309
|
+
|--------|------|
|
|
310
|
+
| [00 — Introduccion](docs/learning/modules/00-intro.md) | Que es CCODE y que problema resuelve |
|
|
311
|
+
| [01 — CLI y Sesion](docs/learning/modules/01-cli-session.md) | Arquitectura CLI, loop persistente, menu contextual |
|
|
312
|
+
| [02 — Contexto Persistente](docs/learning/modules/02-context-persistence.md) | ContextEngine, TaskEngine, estado en `.ccode/` |
|
|
313
|
+
| [03 — Generacion de Contexto](docs/learning/modules/03-context-generation.md) | PromptBuilder, meta-prompts, adaptacion de complejidad |
|
|
314
|
+
| [04 — Proveedores de IA](docs/learning/modules/04-ai-providers.md) | Patron Adapter, Claude, Ollama, AIManager |
|
|
315
|
+
| [05 — Watcher y Verificacion](docs/learning/modules/05-watcher-verify.md) | FileWatcher, verificacion automatica de tareas |
|
|
316
|
+
|
|
317
|
+
Documentos adicionales:
|
|
318
|
+
- [`AGENTS.md`](AGENTS.md) — Roles de ingenieria del proyecto
|
|
319
|
+
- [`SKILLS.md`](SKILLS.md) — Competencias tecnicas requeridas
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Licencia
|
|
324
|
+
|
|
325
|
+
ISC
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
*CCODE no te dice como programar — te dice que construir y se asegura de que no pierdas el rumbo.*
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IAIProvider, IAIConfig } from './provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para Claude (Anthropic).
|
|
4
|
+
*/
|
|
5
|
+
export declare class ClaudeAdapter implements IAIProvider {
|
|
6
|
+
private config;
|
|
7
|
+
constructor(config: IAIConfig);
|
|
8
|
+
getName(): string;
|
|
9
|
+
generate(prompt: string): Promise<string>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para Claude (Anthropic).
|
|
4
|
+
*/
|
|
5
|
+
export class ClaudeAdapter {
|
|
6
|
+
config;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = {
|
|
9
|
+
apiKey: config.apiKey || '',
|
|
10
|
+
model: config.model || 'claude-sonnet-4-20250514',
|
|
11
|
+
baseUrl: config.baseUrl || 'https://api.anthropic.com/v1/messages',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
getName() {
|
|
15
|
+
return `Claude (${this.config.model})`;
|
|
16
|
+
}
|
|
17
|
+
async generate(prompt) {
|
|
18
|
+
if (!this.config.apiKey) {
|
|
19
|
+
throw new Error('API Key de Anthropic no configurada.');
|
|
20
|
+
}
|
|
21
|
+
const response = await axios.post(this.config.baseUrl, {
|
|
22
|
+
model: this.config.model,
|
|
23
|
+
max_tokens: 8096,
|
|
24
|
+
messages: [{ role: 'user', content: prompt }],
|
|
25
|
+
}, {
|
|
26
|
+
headers: {
|
|
27
|
+
'x-api-key': this.config.apiKey,
|
|
28
|
+
'anthropic-version': '2023-06-01',
|
|
29
|
+
'content-type': 'application/json',
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
return response.data.content[0].text;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IAIProvider } from './provider.js';
|
|
2
|
+
export interface ICCODEConfig {
|
|
3
|
+
provider: 'claude' | 'ollama';
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
model?: string;
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Gestiona la configuración y conexión con proveedores de IA.
|
|
10
|
+
*/
|
|
11
|
+
export declare class AIManager {
|
|
12
|
+
private static readonly CONFIG_FILE;
|
|
13
|
+
static loadConfig(): Promise<ICCODEConfig | null>;
|
|
14
|
+
static saveConfig(config: ICCODEConfig): Promise<void>;
|
|
15
|
+
static getProvider(config: ICCODEConfig): IAIProvider;
|
|
16
|
+
static testConnection(config: ICCODEConfig): Promise<boolean>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { ClaudeAdapter } from './claude.js';
|
|
3
|
+
import { OllamaAdapter } from './ollama.js';
|
|
4
|
+
import { FileUtils } from '../utils/files.js';
|
|
5
|
+
/**
|
|
6
|
+
* Gestiona la configuración y conexión con proveedores de IA.
|
|
7
|
+
*/
|
|
8
|
+
export class AIManager {
|
|
9
|
+
static CONFIG_FILE = '.ccode/config.json';
|
|
10
|
+
static async loadConfig() {
|
|
11
|
+
const configPath = path.join(process.cwd(), this.CONFIG_FILE);
|
|
12
|
+
if (await FileUtils.exists(configPath)) {
|
|
13
|
+
return await FileUtils.readJson(configPath);
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
static async saveConfig(config) {
|
|
18
|
+
const configPath = path.join(process.cwd(), this.CONFIG_FILE);
|
|
19
|
+
await FileUtils.writeJson(configPath, config);
|
|
20
|
+
}
|
|
21
|
+
static getProvider(config) {
|
|
22
|
+
switch (config.provider) {
|
|
23
|
+
case 'claude':
|
|
24
|
+
return new ClaudeAdapter({ apiKey: config.apiKey, model: config.model });
|
|
25
|
+
case 'ollama':
|
|
26
|
+
return new OllamaAdapter({ model: config.model, baseUrl: config.baseUrl });
|
|
27
|
+
default:
|
|
28
|
+
throw new Error(`Proveedor desconocido: ${config.provider}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
static async testConnection(config) {
|
|
32
|
+
try {
|
|
33
|
+
const provider = this.getProvider(config);
|
|
34
|
+
await provider.generate('Responde únicamente con la palabra "ok".');
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IAIProvider, IAIConfig } from './provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para Ollama (local).
|
|
4
|
+
*/
|
|
5
|
+
export declare class OllamaAdapter implements IAIProvider {
|
|
6
|
+
private config;
|
|
7
|
+
constructor(config: IAIConfig);
|
|
8
|
+
getName(): string;
|
|
9
|
+
generate(prompt: string): Promise<string>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para Ollama (local).
|
|
4
|
+
*/
|
|
5
|
+
export class OllamaAdapter {
|
|
6
|
+
config;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = {
|
|
9
|
+
model: config.model || 'llama3',
|
|
10
|
+
baseUrl: config.baseUrl || 'http://localhost:11434/api/generate',
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
getName() {
|
|
14
|
+
return `Ollama (${this.config.model})`;
|
|
15
|
+
}
|
|
16
|
+
async generate(prompt) {
|
|
17
|
+
const response = await axios.post(this.config.baseUrl, {
|
|
18
|
+
model: this.config.model,
|
|
19
|
+
prompt,
|
|
20
|
+
stream: false,
|
|
21
|
+
}, {
|
|
22
|
+
headers: { 'Content-Type': 'application/json' },
|
|
23
|
+
timeout: 120000,
|
|
24
|
+
});
|
|
25
|
+
return response.data.response;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const c: {
|
|
2
|
+
primary: import("chalk").ChalkInstance;
|
|
3
|
+
secondary: import("chalk").ChalkInstance;
|
|
4
|
+
accent: import("chalk").ChalkInstance;
|
|
5
|
+
success: import("chalk").ChalkInstance;
|
|
6
|
+
warning: import("chalk").ChalkInstance;
|
|
7
|
+
error: import("chalk").ChalkInstance;
|
|
8
|
+
dim: import("chalk").ChalkInstance;
|
|
9
|
+
bold: import("chalk").ChalkInstance;
|
|
10
|
+
white: import("chalk").ChalkInstance;
|
|
11
|
+
muted: import("chalk").ChalkInstance;
|
|
12
|
+
};
|
|
13
|
+
export declare function showLogo(): void;
|
|
14
|
+
export declare function showHeader(title: string, subtitle?: string): void;
|
|
15
|
+
export declare function showStep(current: number, total: number, message: string): void;
|
|
16
|
+
export declare function showSuccess(message: string): void;
|
|
17
|
+
export declare function showError(message: string): void;
|
|
18
|
+
export declare function showWarning(message: string): void;
|
|
19
|
+
export declare function showInfo(message: string): void;
|
|
20
|
+
export declare function showNextStep(command: string, description: string): void;
|
|
21
|
+
export declare function showDivider(): void;
|
|
22
|
+
export declare function showFileTree(files: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
desc: string;
|
|
25
|
+
}>, indent?: string): void;
|
|
26
|
+
export declare function showProgressBar(completed: number, total: number): string;
|
|
27
|
+
export declare function showWelcome(): void;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
// ─── Paleta de colores CCODE ────────────────────────────────────────
|
|
3
|
+
export const c = {
|
|
4
|
+
primary: chalk.hex('#00B4D8'),
|
|
5
|
+
secondary: chalk.hex('#0077B6'),
|
|
6
|
+
accent: chalk.hex('#90E0EF'),
|
|
7
|
+
success: chalk.hex('#2DC653'),
|
|
8
|
+
warning: chalk.hex('#FFB703'),
|
|
9
|
+
error: chalk.hex('#E63946'),
|
|
10
|
+
dim: chalk.dim,
|
|
11
|
+
bold: chalk.bold,
|
|
12
|
+
white: chalk.white,
|
|
13
|
+
muted: chalk.gray,
|
|
14
|
+
};
|
|
15
|
+
// ─── Logo ASCII con gradiente ───────────────────────────────────────
|
|
16
|
+
const LOGO_LINES = [
|
|
17
|
+
' ██████╗ ██████╗ ██████╗ ██████╗ ███████╗',
|
|
18
|
+
' ██╔════╝██╔════╝ ██╔═══██╗██╔══██╗██╔════╝',
|
|
19
|
+
' ██║ ██║ ██║ ██║██║ ██║█████╗ ',
|
|
20
|
+
' ██║ ██║ ██║ ██║██║ ██║██╔══╝ ',
|
|
21
|
+
' ╚██████╗╚██████╗ ╚██████╔╝██████╔╝███████╗',
|
|
22
|
+
' ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝',
|
|
23
|
+
];
|
|
24
|
+
const GRADIENT = ['#90E0EF', '#48CAE4', '#00B4D8', '#0096C7', '#0077B6', '#023E8A'];
|
|
25
|
+
export function showLogo() {
|
|
26
|
+
console.log('');
|
|
27
|
+
LOGO_LINES.forEach((line, i) => {
|
|
28
|
+
console.log(chalk.hex(GRADIENT[i])(line));
|
|
29
|
+
});
|
|
30
|
+
console.log(c.dim(' Context-Persistent AI Development v2.0'));
|
|
31
|
+
console.log('');
|
|
32
|
+
}
|
|
33
|
+
// ─── Componentes UI ─────────────────────────────────────────────────
|
|
34
|
+
export function showHeader(title, subtitle) {
|
|
35
|
+
console.log('');
|
|
36
|
+
console.log(c.primary(' ┌─ ') + c.bold(title));
|
|
37
|
+
if (subtitle)
|
|
38
|
+
console.log(c.primary(' │ ') + c.dim(subtitle));
|
|
39
|
+
console.log(c.primary(' └' + '─'.repeat(45)));
|
|
40
|
+
console.log('');
|
|
41
|
+
}
|
|
42
|
+
export function showStep(current, total, message) {
|
|
43
|
+
const filled = '●'.repeat(current);
|
|
44
|
+
const empty = '○'.repeat(total - current);
|
|
45
|
+
console.log('');
|
|
46
|
+
console.log(c.primary(` ${filled}${c.dim(empty)} Paso ${current}/${total}`));
|
|
47
|
+
console.log(c.bold(` ${message}`));
|
|
48
|
+
console.log('');
|
|
49
|
+
}
|
|
50
|
+
export function showSuccess(message) {
|
|
51
|
+
console.log(c.success(`\n ✓ ${message}\n`));
|
|
52
|
+
}
|
|
53
|
+
export function showError(message) {
|
|
54
|
+
console.log(c.error(`\n ✗ ${message}\n`));
|
|
55
|
+
}
|
|
56
|
+
export function showWarning(message) {
|
|
57
|
+
console.log(c.warning(`\n ⚠ ${message}\n`));
|
|
58
|
+
}
|
|
59
|
+
export function showInfo(message) {
|
|
60
|
+
console.log(c.primary(` ℹ ${message}`));
|
|
61
|
+
}
|
|
62
|
+
export function showNextStep(command, description) {
|
|
63
|
+
console.log(c.dim(' ─────────────────────────────────────────────'));
|
|
64
|
+
console.log(c.dim(' → Siguiente paso: ') + c.white(command) + c.dim(` - ${description}`));
|
|
65
|
+
console.log('');
|
|
66
|
+
}
|
|
67
|
+
export function showDivider() {
|
|
68
|
+
console.log(c.dim(' ─────────────────────────────────────────────'));
|
|
69
|
+
}
|
|
70
|
+
export function showFileTree(files, indent = ' ') {
|
|
71
|
+
files.forEach((f, i) => {
|
|
72
|
+
const connector = i === files.length - 1 ? '└──' : '├──';
|
|
73
|
+
console.log(c.white(`${indent}${connector} ${f.name}`) + c.dim(` ${f.desc}`));
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export function showProgressBar(completed, total) {
|
|
77
|
+
if (total === 0)
|
|
78
|
+
return '░'.repeat(20) + ' 0%';
|
|
79
|
+
const pct = Math.round((completed / total) * 100);
|
|
80
|
+
const barWidth = 20;
|
|
81
|
+
const filled = Math.round((completed / total) * barWidth);
|
|
82
|
+
const bar = '█'.repeat(filled) + '░'.repeat(barWidth - filled);
|
|
83
|
+
return `${bar} ${pct}% (${completed}/${total})`;
|
|
84
|
+
}
|
|
85
|
+
export function showWelcome() {
|
|
86
|
+
showLogo();
|
|
87
|
+
console.log(c.accent(' Bienvenido a CCODE'));
|
|
88
|
+
console.log(c.dim(' Tu asistente de desarrollo con contexto persistente.'));
|
|
89
|
+
console.log(c.dim(' El contexto vive en el proyecto, no en la conversación.\n'));
|
|
90
|
+
}
|