@korl3one/ccode 2.0.0 → 2.1.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 +35 -11
- package/dist/ai/deepseek.d.ts +11 -0
- package/dist/ai/deepseek.js +35 -0
- package/dist/ai/gemini.d.ts +10 -0
- package/dist/ai/gemini.js +31 -0
- package/dist/ai/groq.d.ts +11 -0
- package/dist/ai/groq.js +35 -0
- package/dist/ai/manager.d.ts +2 -1
- package/dist/ai/manager.js +12 -0
- package/dist/ai/openai.d.ts +10 -0
- package/dist/ai/openai.js +34 -0
- package/dist/cli/index.js +50 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,17 +46,20 @@ Cuando trabajas con IA en un proyecto grande, el contexto se pierde al cambiar d
|
|
|
46
46
|
### Instalacion
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
|
|
49
|
+
npm install -g @korl3one/ccode
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Eso es todo. Ya puedes usar `ccode` en cualquier proyecto.
|
|
53
|
+
|
|
54
|
+
### Contribuir al desarrollo
|
|
55
|
+
|
|
56
|
+
Si quieres colaborar con el proyecto:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
50
59
|
git clone https://github.com/iDevelop25/ccode.git
|
|
51
60
|
cd ccode
|
|
52
|
-
|
|
53
|
-
# Instalar dependencias
|
|
54
61
|
npm install
|
|
55
|
-
|
|
56
|
-
# Compilar
|
|
57
62
|
npm run build
|
|
58
|
-
|
|
59
|
-
# Vincular globalmente
|
|
60
63
|
npm link
|
|
61
64
|
```
|
|
62
65
|
|
|
@@ -145,7 +148,7 @@ La IA compara los **criterios de aceptacion** de cada tarea con los **archivos r
|
|
|
145
148
|
|
|
146
149
|
| Accion | Que hace |
|
|
147
150
|
|--------|----------|
|
|
148
|
-
| **Conectar IA** | Configura Claude
|
|
151
|
+
| **Conectar IA** | Configura tu proveedor de IA (Claude, OpenAI, Gemini, DeepSeek, Groq, Ollama) |
|
|
149
152
|
| **Siguiente tarea** | Muestra la tarea mas prioritaria y ofrece iniciarla |
|
|
150
153
|
| **Verificar progreso** | La IA escanea el proyecto y actualiza estados |
|
|
151
154
|
| **Completar tarea** | Marca como completada, registra en memoria |
|
|
@@ -155,6 +158,23 @@ La IA compara los **criterios de aceptacion** de cada tarea con los **archivos r
|
|
|
155
158
|
|
|
156
159
|
---
|
|
157
160
|
|
|
161
|
+
## Proveedores de IA soportados
|
|
162
|
+
|
|
163
|
+
CCODE funciona con cualquiera de estos proveedores. Solo necesitas una API Key (excepto Ollama que corre local):
|
|
164
|
+
|
|
165
|
+
| Proveedor | Modelos | Nota |
|
|
166
|
+
|-----------|---------|------|
|
|
167
|
+
| **Claude** (Anthropic) | Sonnet 4, Haiku 3.5, Opus 4 | Recomendado |
|
|
168
|
+
| **OpenAI** (ChatGPT) | GPT-4o, GPT-4o mini, GPT-4.1, o3-mini | El mas popular |
|
|
169
|
+
| **Google Gemini** | 2.5 Flash, 2.5 Pro, 2.0 Flash | Gratis con limites |
|
|
170
|
+
| **DeepSeek** | Chat, Reasoner | Economico |
|
|
171
|
+
| **Groq** | Llama 3.3 70B, Llama 3.1 8B, Mixtral 8x7B | Ultra-rapido, tier gratis |
|
|
172
|
+
| **Ollama** | Cualquier modelo local | Sin internet, sin API key |
|
|
173
|
+
|
|
174
|
+
Al ejecutar "Conectar IA" desde el menu, CCODE te muestra los proveedores disponibles, te pide la API Key y te deja elegir el modelo. Prueba la conexion automaticamente antes de guardar.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
158
178
|
## POR QUE CCODE
|
|
159
179
|
|
|
160
180
|
### El problema
|
|
@@ -221,9 +241,13 @@ src/
|
|
|
221
241
|
prompt-builder.ts → Meta-prompts adaptativos, generacion y verificacion
|
|
222
242
|
ai/
|
|
223
243
|
provider.ts → Interfaz comun IAIProvider (patron Adapter)
|
|
224
|
-
claude.ts → Adapter para Claude (
|
|
244
|
+
claude.ts → Adapter para Claude (Anthropic)
|
|
245
|
+
openai.ts → Adapter para OpenAI (ChatGPT)
|
|
246
|
+
gemini.ts → Adapter para Google Gemini
|
|
247
|
+
deepseek.ts → Adapter para DeepSeek
|
|
248
|
+
groq.ts → Adapter para Groq (inferencia ultra-rapida)
|
|
225
249
|
ollama.ts → Adapter para Ollama (modelos locales)
|
|
226
|
-
manager.ts →
|
|
250
|
+
manager.ts → Factory y gestion de configuracion
|
|
227
251
|
utils/
|
|
228
252
|
files.ts → Abstraccion del sistema de archivos
|
|
229
253
|
```
|
|
@@ -311,7 +335,7 @@ El proyecto incluye una guia de aprendizaje modular bajo la metodologia **QP2C**
|
|
|
311
335
|
| [01 — CLI y Sesion](docs/learning/modules/01-cli-session.md) | Arquitectura CLI, loop persistente, menu contextual |
|
|
312
336
|
| [02 — Contexto Persistente](docs/learning/modules/02-context-persistence.md) | ContextEngine, TaskEngine, estado en `.ccode/` |
|
|
313
337
|
| [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,
|
|
338
|
+
| [04 — Proveedores de IA](docs/learning/modules/04-ai-providers.md) | Patron Adapter, 6 proveedores, AIManager |
|
|
315
339
|
| [05 — Watcher y Verificacion](docs/learning/modules/05-watcher-verify.md) | FileWatcher, verificacion automatica de tareas |
|
|
316
340
|
|
|
317
341
|
Documentos adicionales:
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IAIProvider, IAIConfig } from './provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para DeepSeek.
|
|
4
|
+
* Usa formato compatible con OpenAI.
|
|
5
|
+
*/
|
|
6
|
+
export declare class DeepSeekAdapter implements IAIProvider {
|
|
7
|
+
private config;
|
|
8
|
+
constructor(config: IAIConfig);
|
|
9
|
+
getName(): string;
|
|
10
|
+
generate(prompt: string): Promise<string>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para DeepSeek.
|
|
4
|
+
* Usa formato compatible con OpenAI.
|
|
5
|
+
*/
|
|
6
|
+
export class DeepSeekAdapter {
|
|
7
|
+
config;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.config = {
|
|
10
|
+
apiKey: config.apiKey || '',
|
|
11
|
+
model: config.model || 'deepseek-chat',
|
|
12
|
+
baseUrl: config.baseUrl || 'https://api.deepseek.com/v1/chat/completions',
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
getName() {
|
|
16
|
+
return `DeepSeek (${this.config.model})`;
|
|
17
|
+
}
|
|
18
|
+
async generate(prompt) {
|
|
19
|
+
if (!this.config.apiKey) {
|
|
20
|
+
throw new Error('API Key de DeepSeek no configurada.');
|
|
21
|
+
}
|
|
22
|
+
const response = await axios.post(this.config.baseUrl, {
|
|
23
|
+
model: this.config.model,
|
|
24
|
+
max_tokens: 8096,
|
|
25
|
+
messages: [{ role: 'user', content: prompt }],
|
|
26
|
+
}, {
|
|
27
|
+
headers: {
|
|
28
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
},
|
|
31
|
+
timeout: 120000,
|
|
32
|
+
});
|
|
33
|
+
return response.data.choices[0].message.content;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IAIProvider, IAIConfig } from './provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para Google Gemini.
|
|
4
|
+
*/
|
|
5
|
+
export declare class GeminiAdapter implements IAIProvider {
|
|
6
|
+
private config;
|
|
7
|
+
constructor(config: IAIConfig);
|
|
8
|
+
getName(): string;
|
|
9
|
+
generate(prompt: string): Promise<string>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para Google Gemini.
|
|
4
|
+
*/
|
|
5
|
+
export class GeminiAdapter {
|
|
6
|
+
config;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = {
|
|
9
|
+
apiKey: config.apiKey || '',
|
|
10
|
+
model: config.model || 'gemini-2.5-flash',
|
|
11
|
+
baseUrl: config.baseUrl || 'https://generativelanguage.googleapis.com/v1beta/models',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
getName() {
|
|
15
|
+
return `Gemini (${this.config.model})`;
|
|
16
|
+
}
|
|
17
|
+
async generate(prompt) {
|
|
18
|
+
if (!this.config.apiKey) {
|
|
19
|
+
throw new Error('API Key de Google AI no configurada.');
|
|
20
|
+
}
|
|
21
|
+
const url = `${this.config.baseUrl}/${this.config.model}:generateContent?key=${this.config.apiKey}`;
|
|
22
|
+
const response = await axios.post(url, {
|
|
23
|
+
contents: [{ parts: [{ text: prompt }] }],
|
|
24
|
+
generationConfig: { maxOutputTokens: 8096 },
|
|
25
|
+
}, {
|
|
26
|
+
headers: { 'Content-Type': 'application/json' },
|
|
27
|
+
timeout: 120000,
|
|
28
|
+
});
|
|
29
|
+
return response.data.candidates[0].content.parts[0].text;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IAIProvider, IAIConfig } from './provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para Groq (inferencia ultra-rápida).
|
|
4
|
+
* Usa formato compatible con OpenAI.
|
|
5
|
+
*/
|
|
6
|
+
export declare class GroqAdapter implements IAIProvider {
|
|
7
|
+
private config;
|
|
8
|
+
constructor(config: IAIConfig);
|
|
9
|
+
getName(): string;
|
|
10
|
+
generate(prompt: string): Promise<string>;
|
|
11
|
+
}
|
package/dist/ai/groq.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para Groq (inferencia ultra-rápida).
|
|
4
|
+
* Usa formato compatible con OpenAI.
|
|
5
|
+
*/
|
|
6
|
+
export class GroqAdapter {
|
|
7
|
+
config;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.config = {
|
|
10
|
+
apiKey: config.apiKey || '',
|
|
11
|
+
model: config.model || 'llama-3.3-70b-versatile',
|
|
12
|
+
baseUrl: config.baseUrl || 'https://api.groq.com/openai/v1/chat/completions',
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
getName() {
|
|
16
|
+
return `Groq (${this.config.model})`;
|
|
17
|
+
}
|
|
18
|
+
async generate(prompt) {
|
|
19
|
+
if (!this.config.apiKey) {
|
|
20
|
+
throw new Error('API Key de Groq no configurada.');
|
|
21
|
+
}
|
|
22
|
+
const response = await axios.post(this.config.baseUrl, {
|
|
23
|
+
model: this.config.model,
|
|
24
|
+
max_tokens: 8096,
|
|
25
|
+
messages: [{ role: 'user', content: prompt }],
|
|
26
|
+
}, {
|
|
27
|
+
headers: {
|
|
28
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
},
|
|
31
|
+
timeout: 60000,
|
|
32
|
+
});
|
|
33
|
+
return response.data.choices[0].message.content;
|
|
34
|
+
}
|
|
35
|
+
}
|
package/dist/ai/manager.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IAIProvider } from './provider.js';
|
|
2
|
+
export type ProviderName = 'claude' | 'openai' | 'gemini' | 'deepseek' | 'groq' | 'ollama';
|
|
2
3
|
export interface ICCODEConfig {
|
|
3
|
-
provider:
|
|
4
|
+
provider: ProviderName;
|
|
4
5
|
apiKey?: string;
|
|
5
6
|
model?: string;
|
|
6
7
|
baseUrl?: string;
|
package/dist/ai/manager.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
import { ClaudeAdapter } from './claude.js';
|
|
3
|
+
import { OpenAIAdapter } from './openai.js';
|
|
4
|
+
import { GeminiAdapter } from './gemini.js';
|
|
5
|
+
import { DeepSeekAdapter } from './deepseek.js';
|
|
6
|
+
import { GroqAdapter } from './groq.js';
|
|
3
7
|
import { OllamaAdapter } from './ollama.js';
|
|
4
8
|
import { FileUtils } from '../utils/files.js';
|
|
5
9
|
/**
|
|
@@ -22,6 +26,14 @@ export class AIManager {
|
|
|
22
26
|
switch (config.provider) {
|
|
23
27
|
case 'claude':
|
|
24
28
|
return new ClaudeAdapter({ apiKey: config.apiKey, model: config.model });
|
|
29
|
+
case 'openai':
|
|
30
|
+
return new OpenAIAdapter({ apiKey: config.apiKey, model: config.model });
|
|
31
|
+
case 'gemini':
|
|
32
|
+
return new GeminiAdapter({ apiKey: config.apiKey, model: config.model });
|
|
33
|
+
case 'deepseek':
|
|
34
|
+
return new DeepSeekAdapter({ apiKey: config.apiKey, model: config.model });
|
|
35
|
+
case 'groq':
|
|
36
|
+
return new GroqAdapter({ apiKey: config.apiKey, model: config.model });
|
|
25
37
|
case 'ollama':
|
|
26
38
|
return new OllamaAdapter({ model: config.model, baseUrl: config.baseUrl });
|
|
27
39
|
default:
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IAIProvider, IAIConfig } from './provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* Adaptador para OpenAI (ChatGPT).
|
|
4
|
+
*/
|
|
5
|
+
export declare class OpenAIAdapter 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 OpenAI (ChatGPT).
|
|
4
|
+
*/
|
|
5
|
+
export class OpenAIAdapter {
|
|
6
|
+
config;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = {
|
|
9
|
+
apiKey: config.apiKey || '',
|
|
10
|
+
model: config.model || 'gpt-4o',
|
|
11
|
+
baseUrl: config.baseUrl || 'https://api.openai.com/v1/chat/completions',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
getName() {
|
|
15
|
+
return `OpenAI (${this.config.model})`;
|
|
16
|
+
}
|
|
17
|
+
async generate(prompt) {
|
|
18
|
+
if (!this.config.apiKey) {
|
|
19
|
+
throw new Error('API Key de OpenAI 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
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
28
|
+
'Content-Type': 'application/json',
|
|
29
|
+
},
|
|
30
|
+
timeout: 120000,
|
|
31
|
+
});
|
|
32
|
+
return response.data.choices[0].message.content;
|
|
33
|
+
}
|
|
34
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -39,37 +39,73 @@ async function promptAIConfig() {
|
|
|
39
39
|
message: 'Proveedor de IA:',
|
|
40
40
|
choices: [
|
|
41
41
|
{ name: ' Claude (Anthropic) — Recomendado', value: 'claude' },
|
|
42
|
-
{ name: '
|
|
42
|
+
{ name: ' OpenAI (ChatGPT)', value: 'openai' },
|
|
43
|
+
{ name: ' Google Gemini', value: 'gemini' },
|
|
44
|
+
{ name: ' DeepSeek', value: 'deepseek' },
|
|
45
|
+
{ name: ' Groq (ultra-rápido)', value: 'groq' },
|
|
46
|
+
{ name: ' Ollama (local, sin API key)', value: 'ollama' },
|
|
43
47
|
],
|
|
44
48
|
}]);
|
|
45
49
|
const config = { provider };
|
|
46
|
-
|
|
50
|
+
// Modelos por proveedor
|
|
51
|
+
const modelChoices = {
|
|
52
|
+
claude: [
|
|
53
|
+
{ name: 'Claude Sonnet 4 (recomendado)', value: 'claude-sonnet-4-20250514' },
|
|
54
|
+
{ name: 'Claude Haiku 3.5 (rápido)', value: 'claude-haiku-4-5-20251001' },
|
|
55
|
+
{ name: 'Claude Opus 4 (máxima calidad)', value: 'claude-opus-4-20250514' },
|
|
56
|
+
],
|
|
57
|
+
openai: [
|
|
58
|
+
{ name: 'GPT-4o (recomendado)', value: 'gpt-4o' },
|
|
59
|
+
{ name: 'GPT-4o mini (rápido)', value: 'gpt-4o-mini' },
|
|
60
|
+
{ name: 'GPT-4.1 (último)', value: 'gpt-4.1' },
|
|
61
|
+
{ name: 'o3-mini (razonamiento)', value: 'o3-mini' },
|
|
62
|
+
],
|
|
63
|
+
gemini: [
|
|
64
|
+
{ name: 'Gemini 2.5 Flash (recomendado)', value: 'gemini-2.5-flash' },
|
|
65
|
+
{ name: 'Gemini 2.5 Pro (máxima calidad)', value: 'gemini-2.5-pro' },
|
|
66
|
+
{ name: 'Gemini 2.0 Flash (rápido)', value: 'gemini-2.0-flash' },
|
|
67
|
+
],
|
|
68
|
+
deepseek: [
|
|
69
|
+
{ name: 'DeepSeek Chat (recomendado)', value: 'deepseek-chat' },
|
|
70
|
+
{ name: 'DeepSeek Reasoner', value: 'deepseek-reasoner' },
|
|
71
|
+
],
|
|
72
|
+
groq: [
|
|
73
|
+
{ name: 'Llama 3.3 70B (recomendado)', value: 'llama-3.3-70b-versatile' },
|
|
74
|
+
{ name: 'Llama 3.1 8B (rápido)', value: 'llama-3.1-8b-instant' },
|
|
75
|
+
{ name: 'Mixtral 8x7B', value: 'mixtral-8x7b-32768' },
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
// API Key (todos excepto Ollama)
|
|
79
|
+
if (provider !== 'ollama') {
|
|
80
|
+
const providerNames = {
|
|
81
|
+
claude: 'Anthropic', openai: 'OpenAI', gemini: 'Google AI',
|
|
82
|
+
deepseek: 'DeepSeek', groq: 'Groq',
|
|
83
|
+
};
|
|
47
84
|
const { apiKey } = await inquirer.prompt([{
|
|
48
85
|
type: 'password',
|
|
49
86
|
name: 'apiKey',
|
|
50
|
-
message:
|
|
87
|
+
message: `API Key de ${providerNames[provider]}:`,
|
|
51
88
|
mask: '*',
|
|
52
89
|
validate: (v) => v.length > 10 || 'Ingresa una API Key válida',
|
|
53
90
|
}]);
|
|
54
91
|
config.apiKey = apiKey;
|
|
92
|
+
}
|
|
93
|
+
// Selección de modelo
|
|
94
|
+
if (provider === 'ollama') {
|
|
55
95
|
const { model } = await inquirer.prompt([{
|
|
56
|
-
type: '
|
|
96
|
+
type: 'input',
|
|
57
97
|
name: 'model',
|
|
58
|
-
message: 'Modelo:',
|
|
59
|
-
|
|
60
|
-
{ name: 'Claude Sonnet 4 (recomendado)', value: 'claude-sonnet-4-20250514' },
|
|
61
|
-
{ name: 'Claude Haiku 3.5 (rápido)', value: 'claude-haiku-4-5-20251001' },
|
|
62
|
-
{ name: 'Claude Opus 4 (máxima calidad)', value: 'claude-opus-4-20250514' },
|
|
63
|
-
],
|
|
98
|
+
message: 'Modelo de Ollama:',
|
|
99
|
+
default: 'llama3',
|
|
64
100
|
}]);
|
|
65
101
|
config.model = model;
|
|
66
102
|
}
|
|
67
103
|
else {
|
|
68
104
|
const { model } = await inquirer.prompt([{
|
|
69
|
-
type: '
|
|
105
|
+
type: 'select',
|
|
70
106
|
name: 'model',
|
|
71
|
-
message: 'Modelo
|
|
72
|
-
|
|
107
|
+
message: 'Modelo:',
|
|
108
|
+
choices: modelChoices[provider],
|
|
73
109
|
}]);
|
|
74
110
|
config.model = model;
|
|
75
111
|
}
|
|
@@ -353,7 +389,7 @@ async function handleConnect() {
|
|
|
353
389
|
}
|
|
354
390
|
else {
|
|
355
391
|
spinner.fail(c.error('No se pudo conectar'));
|
|
356
|
-
showError('Verifica
|
|
392
|
+
showError('Verifica tu API Key, conexión a internet, o que Ollama esté corriendo.');
|
|
357
393
|
}
|
|
358
394
|
}
|
|
359
395
|
// ─── PLAN ───────────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@korl3one/ccode",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "CLI de contexto persistente para desarrollo asistido por IA. Genera documentacion, arquitectura, reglas y tareas verificables.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cli/index.js",
|