@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 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,12 @@
1
+ /**
2
+ * Interfaz común para proveedores de IA.
3
+ */
4
+ export interface IAIProvider {
5
+ generate(prompt: string): Promise<string>;
6
+ getName(): string;
7
+ }
8
+ export interface IAIConfig {
9
+ apiKey?: string;
10
+ model?: string;
11
+ baseUrl?: string;
12
+ }
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};